package com.bj58.ecdata.redis;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.UUID;
import java.util.concurrent.Callable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

import org.apache.commons.lang3.StringUtils;
import org.apache.commons.pool.impl.GenericObjectPool;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import redis.clients.jedis.Builder;
import redis.clients.jedis.BuilderFactory;
import redis.clients.jedis.Client;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisShardInfo;
import redis.clients.jedis.Pipeline;
import redis.clients.jedis.ShardedJedis;
import redis.clients.jedis.ShardedJedisPool;
import redis.clients.jedis.Tuple;
import redis.clients.util.Pool;
import redis.clients.util.SafeEncoder;

import com.bj58.ecdata.redis.RedisData.RedisKeyByteMemByte;
import com.bj58.ecdata.redis.RedisData.RedisKeyMemByte;
import com.bj58.ecdata.redis.RedisData.RedisKeyMemObj;
import com.bj58.ecdata.redis.RedisData.RedisKeyMemStr;
import com.bj58.ecdata.redis.RedisHashData.RedisKeyHashByteMemByte;
import com.bj58.ecdata.redis.RedisHashData.RedisKeyHashMemByte;
import com.bj58.ecdata.redis.RedisHashData.RedisKeyHashMemObj;
import com.bj58.ecdata.redis.RedisHashData.RedisKeyHashMemStr;
import com.bj58.ecdata.redis.RedisSortData.RedisKeySortByteMemByte;
import com.bj58.ecdata.redis.RedisSortData.RedisKeySortMemByte;
import com.bj58.ecdata.redis.RedisSortData.RedisKeySortMemObj;
import com.bj58.ecdata.redis.RedisSortData.RedisKeySortMemStr;
import com.bj58.ecdata.redis.exception.JedisXValueNotSupportException;
import com.bj58.ecdata.redis.util.JedisXSerializeUtil;
import com.bj58.ecdata.thread.NamedThreadFactory;
import com.bj58.ecdata.util.ReflectUtil;




public class JedisX {
	protected static final Logger log = LoggerFactory.getLogger(JedisX.class);

	private final int defaultIndex = 0;

	private final JedisBean bean;

	private final JedisPoolConfig jedisPoolConfig;

	private final ShardedJedisPool shardedJedisPool;
	
	private int timeout = 30;
	
	private final ScheduledExecutorService  scheduledExecutorService = Executors.newScheduledThreadPool(1);

	private final ExecutorService executorService = Executors
			.newCachedThreadPool(new NamedThreadFactory("jedisx"));


	// ============================初始化==================================

	public JedisX(JedisBean bean, JedisPoolConfig jedisPoolConfig, int timeout) {
		this.bean = bean;
		this.jedisPoolConfig = jedisPoolConfig;
		//timeout必须在sharedJedisPool之前设置
		this.timeout = timeout;
		this.shardedJedisPool = initialShardedPool();	
	}

	public void startPrintPoolInfo(){
			
			scheduledExecutorService.scheduleAtFixedRate(new Runnable() {

				@Override
				public void run() {
					try{
					Field targetField = Pool.class.getDeclaredField("internalPool");
					targetField.setAccessible(true);
					final GenericObjectPool internalPool = (GenericObjectPool)targetField.get(shardedJedisPool);
						if(internalPool != null){
							log.info("ShardedJedisPool------maxActive:"+internalPool.getMaxActive()+",active:" + internalPool.getNumActive() + ",idle:" + internalPool.getNumIdle());
						}	
					}
					catch(Exception e){
						log.error("print JedisX pool info error. reason:"+e.getMessage());
						//e.printStackTrace();
					}	
				}
				
			},2,1,TimeUnit.SECONDS);			
			
	}
	
	public void stopPrintPoolInfo(){
		if( scheduledExecutorService != null ){
			scheduledExecutorService.shutdownNow();				
		}
	}
	
	public int getDBIndex(String key) {
		int retIndex = defaultIndex;
		Map<String, Integer> dbIndexMap = bean.getDbIndexMap();
		if (dbIndexMap != null) {
			String dbKey = key == null ? key : key.split("_")[0];
			Integer dbIndex = dbIndexMap.get(dbKey);
			if (dbIndex != null) {
				retIndex = dbIndex;
			}
		}
		return retIndex;
	}

	private ShardedJedisPool initialShardedPool() {
		String conn = bean.getMasterAddress();
		String password = bean.getPassword();
		List<JedisShardInfo> shards = new ArrayList<JedisShardInfo>();
		String addrs[] = conn.split(",");
		int length = addrs.length;
		for (int i = 0; i < length; i++) {
			String addr = addrs[i];
			String host = addr.split(":")[0];
			int port = Integer.parseInt(addr.split(":")[1]);
			JedisShardInfo info = new JedisShardInfo(host, port, timeout,"redis-shard-"
					+ addr);
			if (StringUtils.isNotEmpty(password))
				info.setPassword(password);
			shards.add(info);
		}
		return new ShardedJedisPool(jedisPoolConfig, shards);
	}

	// ============================初始化结束==================================

	/**
	 * 
	 * @param keys
	 * @return
	 */
	private Map<String, List<String>> devideKeys(Collection<String> keys) {
		Map<JedisShardInfo, List<String>> map = new HashMap<JedisShardInfo, List<String>>();
		Map<String, List<String>> result = new HashMap<String, List<String>>();
		ShardedJedis shardJedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			for (String key : keys) {
				JedisShardInfo jedisShardInfo = shardJedis.getShardInfo(key);
				List<String> keysList = map.get(jedisShardInfo);

				if (keysList == null) {
					keysList = new ArrayList<String>();
					map.put(jedisShardInfo, keysList);
				}
				keysList.add(key);
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage(), e);
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		for (List<String> list : map.values()) {
			result.put(list.iterator().next(), list);
		}
		return result;
	}

	/******************************* below:expire ******************************/
	/**
	 * 对key设置过期时间
	 * 
	 * @param key
	 * @param expireSeconds
	 * @return Integer reply, specifically: 1: the timeout was set. 0: the
	 *         timeout was not set since the key already has an associated
	 *         timeout (this may happen only in Redis versions < 2.1.3, Redis >=
	 *         2.1.3 will happily update the timeout), or the key does not
	 *         exist.
	 */

	public Long expire(String key, int expireSeconds) {

		return expire(key, SafeEncoder.encode(key), expireSeconds);
	}

	private Long expire(String key, byte[] bytekey, int expireSeconds) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);

			//
			if (jedis != null) {
				Long ret = jedis.expire(bytekey, expireSeconds);
				return ret;
			}
			//

		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/****************************** above:expire *************************/

	/***************************** below:set ********************************************/
	/**
	 * 缓存一个字符串。与getString(key)、multiGetString(List\<keys\>)配合使用,
	 * 缓存成功后无法通过getObject(key)取出对象。
	 * 若后续需要对此String进行append、incr、decr操作，则不能用setObject替换
	 * 
	 * @param key
	 * @param expireSecond
	 *            过期时间，单位为秒（0和负数表示不设置过期）
	 * @param value
	 * @return "OK" or "failed"
	 */

	public String setString(final String key, int expireSecond, String value) {
		return setByteArr(key, expireSecond, SafeEncoder.encode(value));
	}

	/**
	 * 缓存一个对象。与getObject(key)、multiGetObject(List\<keys\>)配合使用
	 * 
	 * @param key
	 * @param expireSecond
	 *            过期时间，单位为秒（0和负数表示不设置过期）
	 * @param value
	 *            可序列化对象（实现Serializable接口）
	 * @return "OK" or "failed"
	 */

	public String setObject(final String key, int expireSecond, Object value) {
		return setByteArr(key, expireSecond, serialize(value));
	}

	/**
	 * 缓存一个数据块。与getByteArr(key)、multiGetByteArr(List\<keys\>)配合使用
	 * 
	 * @param key
	 * @param expireSecond
	 *            过期时间，单位为秒（0和负数表示不设置过期）
	 * @param value
	 * @return "OK" or "failed"
	 */

	public String setByteArr(final String key, int expireSecond, byte[] value) {
		valueTypeAssert(value);
		return set(key, SafeEncoder.encode(key), expireSecond, value);
	}

	private String set(String key, final byte[] bytekey, int expireSecond,
			byte[] value) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);

			if (jedis != null) {
				String ret = null;
				if (expireSecond > 0) {
					ret = jedis.setex(bytekey, expireSecond, value);
				} else {
					ret = jedis.set(bytekey, value);
				}
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}

		return "failed";
	}

	/******************************** above:set ********************************************/

	/***************************** below:multiset *****************************************/
	/**
	 * 缓存多个字符串。与getString(key)。multiGetString(List\<keys\>)配合使用。
	 * 若后续需要对此String进行append、incr、decr操作，则不能用setObject替换
	 * 
	 * @param keyValue
	 * @param expireSecond
	 *            过期时间，单位为秒（0和负数表示不设置过期）
	 * @return "OK" or "failed"
	 */

	public String multiSetString(final Map<String, String> keyValue,
			int expireSecond) {
		Map<String, byte[]> keyValuebMap = new HashMap<String, byte[]>();
		for (String key : keyValue.keySet()) {
			String value = keyValue.get(key);
			if (value != null) {
				keyValuebMap.put(key, SafeEncoder.encode(value));
			}
		}
		return multiSet(keyValuebMap, expireSecond);
	}

	/**
	 * 缓存多个对象。与getObject(key)、multiGetObject(List\<keys\>)配合使用
	 * 
	 * @param keyValue
	 *            key与可序列化对象（实现Serializable接口）的映射Map
	 * @param expireSecond
	 *            过期时间，单位为秒（0和负数表示不设置过期）
	 * @return "OK" or "failed"
	 */

	public String multiSetObject(Map<String, Object> keyValue, int expireSecond) {
		Map<String, byte[]> keyValuebMap = new HashMap<String, byte[]>();
		for (String key : keyValue.keySet()) {
			Object value = keyValue.get(key);
			if (value != null) {
				keyValuebMap.put(key, serialize(value));
			}
		}
		return multiSet(keyValuebMap, expireSecond);
	}

	/**
	 * 缓存多个数据块。与getByteArr(key)、multiGetByteArr(List\<keys\>)配合使用
	 * 
	 * @param keyValue
	 *            key与可序列化对象（实现Serializable接口）的映射Map
	 * @param expireSecond
	 *            过期时间，单位为秒（0和负数表示不设置过期）
	 * @return "OK" or "failed"
	 */

	public String multiSetByteArr(Map<String, byte[]> keyValue, int expireSecond) {
		Map<String, byte[]> keyValuebMap = new HashMap<String, byte[]>();
		for (String key : keyValue.keySet()) {
			byte[] value = keyValue.get(key);
			if (value != null) {
				keyValuebMap.put(key, value);
			}
		}
		return multiSet(keyValuebMap, expireSecond);
	}

	private String multiSet(Map<String, byte[]> keyValuebMap, int expireSecond) {
		String ret = null;
		Map<String, List<String>> nodeToKeys = devideKeys(keyValuebMap.keySet());
		for (String key : nodeToKeys.keySet()) {
			List<String> thisKeys = nodeToKeys.get(key);
			if (thisKeys != null && thisKeys.size() > 0) {
				ret = multiSet(key, expireSecond,
						getKeyValueBArrArr(thisKeys, keyValuebMap));
			}
		}
		return ret;
	}

	private String multiSet(String key, int expireSecond,
			final byte[]... keyValues) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				String ret = null;
				ret = jedis.mset(keyValues);
				if (expireSecond > 0) { // it's
					for (int i = 0; i < keyValues.length; i += 2) {
						jedis.expire(keyValues[i], expireSecond);
					}
				}
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return "failed";
	}

	/******************************** above:multiset *****************************************/

	/**
	 * *****************************below:setIfNotExist*************************
	 * **********
	 */
	/**
	 * 类似于setString，不同的是只有在此key不存在时才缓存成功
	 * 
	 * @param key
	 * @param expireSecond
	 * @param value
	 * @return 1表示缓存成功，0表示key已存在缓存不成功，-1表示服务器异常
	 */

	public long setStringIfNotExist(final String key, int expireSecond,
			String value) {
		return setByteArrIfNotExist(key, expireSecond,
				SafeEncoder.encode(value));
	}

	/**
	 * 类似于setObject，不同的是只有在此key不存在时才缓存成功
	 * 
	 * @param key
	 * @param expireSecond
	 * @param value
	 * @return 1表示缓存成功，0表示key已存在缓存不成功，-1表示服务器异常
	 */

	public long setObjectIfNotExist(final String key, int expireSecond,
			Object value) {
		return setByteArrIfNotExist(key, expireSecond, serialize(value));
	}

	/**
	 * 类似于setByteArr，不同的是只有在此key不存在时才缓存成功
	 * 
	 * @param key
	 * @param expireSecond
	 * @param value
	 * @return 1表示缓存成功，0表示key已存在缓存不成功，-1表示服务器异常
	 */

	public long setByteArrIfNotExist(final String key, int expireSecond,
			byte[] value) {
		valueTypeAssert(value);
		return setIfNotExist(key, SafeEncoder.encode(key), expireSecond, value);

	}

	private long setIfNotExist(String key, final byte[] bytekey,
			int expireSecond, byte[] value) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.setnx(bytekey, value);
				if (expireSecond > 0) {
					jedis.expire(bytekey, expireSecond);
				}
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return -1L;
	}

	/******************************** above:setIfNotExist *********************************/

	/***************************** below:multisetInNotExit *****************************/
	/**
	 * 类似于multiSetString，不同的是只有在此key不存在时才缓存成功
	 * 
	 * @param keyValue
	 * @param expireSecond
	 * @return 返回非负数值，表示本次缓存成功k-v数;返回负数值，表示服务端异常
	 */

	public long multiSetStringIfNotExist(final Map<String, String> keyValue,
			int expireSecond) {
		Map<String, byte[]> keyValuebMap = new HashMap<String, byte[]>();
		for (String key : keyValue.keySet()) {
			String value = keyValue.get(key);
			if (value != null) {
				keyValuebMap.put(key, SafeEncoder.encode(value));
			}
		}
		return multiSetIfNotExist(keyValuebMap, expireSecond);
	}

	/**
	 * 类似于multiSetObject，不同的是只有在此key不存在时才缓存成功
	 * 
	 * @param keyValue
	 * @param expireSecond
	 * @return 返回非负数值，表示本次缓存成功k-v数;返回负数值，表示服务端异常
	 */

	public long multiSetObjectIfNotExist(Map<String, Object> keyValue,
			int expireSecond) {
		Map<String, byte[]> keyValuebMap = new HashMap<String, byte[]>();
		for (String key : keyValue.keySet()) {
			Object value = keyValue.get(key);
			if (value != null) {
				keyValuebMap.put(key, serialize(value));
			}
		}
		return multiSetIfNotExist(keyValuebMap, expireSecond);
	}

	/**
	 * 类似于multiSetByteArr，不同的是只有在此key不存在时才缓存成功
	 * 
	 * @param keyValue
	 * @param expireSecond
	 * @return 返回非负数值，表示本次缓存成功k-v数;返回负数值，表示服务端异常
	 */

	public long multiSetByteArrIfNotExist(Map<String, byte[]> keyValue,
			int expireSecond) {
		Map<String, byte[]> keyValuebMap = new HashMap<String, byte[]>();
		for (String key : keyValue.keySet()) {
			byte[] value = keyValue.get(key);
			if (value != null) {
				keyValuebMap.put(key, value);
			}
		}
		return multiSetIfNotExist(keyValuebMap, expireSecond);
	}

	private long multiSetIfNotExist(Map<String, byte[]> keyValuebMap,
			int expireSecond) {
		long ret = 0;
		Map<String, List<String>> nodeToKeys = devideKeys(keyValuebMap.keySet());
		for (String key : nodeToKeys.keySet()) {
			List<String> thisKeys = nodeToKeys.get(key);
			if (thisKeys != null && thisKeys.size() > 0) {
				ret += multiSetIfNotExist(key, expireSecond,
						getKeyValueBArrArr(thisKeys, keyValuebMap));
			}
		}
		return ret;
	}

	private long multiSetIfNotExist(String key, int expireSecond,
			final byte[]... keyValues) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				long ret = jedis.msetnx(keyValues);
				if (expireSecond > 0) { // it's
					for (int i = 0; i < keyValues.length; i += 2) {
						jedis.expire(keyValues[i], expireSecond);
					}
				}
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return -1L;
	}

	/******************************** above:multisetIfNotExit ********************************/

	
	public String getRedisInfo(String key){
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				return jedis.getClient().getHost()+":"+jedis.getClient().getPort();
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}
	
	/***************************** below:get *******************************************/
	/**
	 * 取出缓存的字符串，与setString()配合使用。.
	 * 需要注意的时通过setObject(key,str)之类的接口缓存的字符串对象，无法通过此接口取出正确数据
	 * 
	 * @param key
	 * @return
	 */

	public String getString(String key) {
		byte[] ret = get(key, SafeEncoder.encode(key));
		if (ret != null) {
			return SafeEncoder.encode(ret);
		}
		return null;

	}
	
	public Set<String> keys(String key) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			return jedis.keys(key);
		} catch (Exception e) {		
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			if(jedis != null){
				log.error("JdedisX.keys() "+e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
				jedis = null;
			}
			else{
				log.error("JdedisX.keys() "+e.getMessage());
			}
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * 取出缓存的字符串，与setObject()配合使用。.
	 * 需要注意的时通过setString(key,str)之类的接口缓存的字符串对象，无法通过此接口取出正确数据
	 * 
	 * @param key
	 * @return
	 */

	public Object getObject(String key) {
		byte[] ret = get(key, SafeEncoder.encode(key));
		if (ret != null) {
			return deserialize(ret);
		}

		return null;
	}
	
	public Object getObject(final String key,long time){
		FutureTask<Object> future = new FutureTask<Object>(new Callable<Object>() {
			@Override
			public Object call() throws Exception {
				return getObject(key);
			}
		});
		executorService.execute(future);
		try {
			return future.get(time, TimeUnit.MILLISECONDS);
		} catch (Exception e) {
			Jedis jedis=null ;
			ShardedJedis shardJedis = null;
			try{
				shardJedis = shardedJedisPool.getResource();
				jedis = shardJedis.getShard(key);
				log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
				jedis = null;
			}catch(Exception ex){
			}finally{
				if (shardJedis != null) {
					shardedJedisPool.returnResource(shardJedis);
				}
			}
			
		} 
		return null;
	}

	/**
	 * 取出缓存的字符串，与setByteArr()配合使用。.
	 * 
	 * @param key
	 * @return
	 */

	public byte[] getByteArr(String key) {
		byte[] ret = get(key, SafeEncoder.encode(key));
		return ret;
	}

	private byte[] get(String key, byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			
			//jedis.select(dbIndex);
			if (jedis != null) {
				byte[] ret = jedis.get(bytekey);
				return ret;
			}
		} catch (Exception e) {		
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			if(jedis != null){
				log.error("JdedisX.get() "+e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
				jedis = null;
			}
			else{
				log.error("JdedisX.get() "+e.getMessage());
			}
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/******************************** above:get ********************************************/

	/**
	 * *****************************below:multiget******************************
	 * **********
	 */
	/**
	 * 一次取出多个缓存的String对象
	 * 
	 * @param keys
	 * @return
	 */

	public Map<String, String> multiGetString(List<String> keys) {
		Map<String, String> ret = new HashMap<String, String>();
		Map<String, byte[]> temp = multiGetByteArr(keys);
		for (String key : temp.keySet()) {
			byte[] value = temp.get(key);
			if (value != null) {
				ret.put(key, SafeEncoder.encode(value));
			} else {
				ret.put(key, null);
			}
		}
		return ret;
	}

	/**
	 * 一次取出多个缓存的Object
	 * 
	 * @param keys
	 * @return
	 */

	public Map<String, Object> multiGetObject(List<String> keys) {
		Map<String, Object> ret = new HashMap<String, Object>();
		Map<String, byte[]> temp = multiGetByteArr(keys);
		for (String key : temp.keySet()) {
			byte[] value = temp.get(key);
			if (value != null) {
				ret.put(key, deserialize(value));
			} else {
				ret.put(key, null);
			}
		}
		return ret;
	}
	
	public Map<String, Object> multiGetObject(final List<String> keys,long time) {
		FutureTask<Map<String, Object>> future = new FutureTask<Map<String, Object>>(new Callable<Map<String, Object>>() {
			@Override
			public Map<String, Object> call() throws Exception {
				return multiGetObject(keys);
			}
		});
		executorService.execute(future);
		try {
			return future.get(time, TimeUnit.MILLISECONDS);
		} catch (Exception e) {
			log.error("multiGetObject error",e);
		} 
		return new HashMap<String, Object>();
	}

	/**
	 * 一次取出多个缓存的数据块
	 * 
	 * @param keys
	 * @return
	 */

	// public Map<String, byte[]> multiGetByteArr(List<String> keys) {
	// Map<String, byte[]> ret = new HashMap<String, byte[]>();
	// Map<String, List<String>> nodeToKeys = devideKeys(keys);
	// for (final String key : nodeToKeys.keySet()) {
	// List<String> thisKeys = nodeToKeys.get(key);
	// if (thisKeys != null && thisKeys.size() > 0) {
	// Map<String, byte[]> thisret = multiGet(key, getBArrArr(thisKeys));
	// if (thisret != null) {
	// ret.putAll(thisret);
	// }
	// }
	// }
	//
	// return ret;
	// }

	/**
	 * 一次取出多个缓存的数据块，多线程取
	 * 
	 * @param keys
	 * @return
	 */

	public Map<String, byte[]> multiGetByteArr(List<String> keys) {
		final Map<String, byte[]> ret = new ConcurrentHashMap<String, byte[]>();
		final Map<String, List<String>> nodeToKeys = devideKeys(keys);
		final CountDownLatch cdl = new CountDownLatch(nodeToKeys.keySet()
				.size());

		for (final String key : nodeToKeys.keySet()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
					try {
						List<String> thisKeys = nodeToKeys.get(key);
						if (thisKeys != null && thisKeys.size() > 0) {
							Map<String, byte[]> thisret = multiGet(key,
									getBArrArr(thisKeys));
							if (thisret != null) {
								ret.putAll(thisret);
							}
						}
					} finally {
						cdl.countDown();
					}
				}
			});

		}
		try {
			cdl.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return ret;
	}

	private Map<String, byte[]> multiGet(String key, byte[]... keys) {
		Map<String, byte[]> map = new HashMap<String, byte[]>();
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				List<byte[]> ret = jedis.mget(keys);
				for (int i = ret.size() - 1; i >= 0; i--) {
					if (ret.get(i) != null)
						map.put(SafeEncoder.encode(keys[i]), ret.get(i));
				}
				return map;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return map;
	}

	/******************************** above:multiget *****************************************/

	/***************************** below:exists *****************************************/
	/**
	 * 查询某key是否存在。无论是通过setString,还是setObject，setByteArr等任何接口缓存了数据，只要数据仍在有效期内，
	 * 有将返回true
	 * 
	 * @param key
	 * @return
	 */

	public Boolean exists(String key) {
		boolean result = exists(key, SafeEncoder.encode(key));
		return result;
	}

	private Boolean exists(String key, byte[] bytekey) {

		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Boolean ret = jedis.exists(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return false;
	}

	/******************************** above:exists ********************************************/

	/**
	 * *****************************below:delete,multidelte*********************
	 * *************
	 */
	/**
	 * 删除某个缓存k-v对
	 * 
	 * @param key
	 * @return 0表示key不存在或未删除成功，1表示key存在并删除成功
	 */

	public long delete(String key) {

		return delete(key, SafeEncoder.encode(key));

	}

	public long deleteWithSharding(String shardingKey, String key) {

		return delete(shardingKey, key, SafeEncoder.encode(key));

	}

	/**
	 * 一次删除多个k-v对
	 * 
	 * @param keys
	 * @return 成功删除的k-v对的数目
	 */

	public long multiDelete(List<String> keys) {
		Map<String, List<String>> nodeToKeys = devideKeys(keys);
		long ret = 0;
		for (String key : nodeToKeys.keySet()) {
			List<String> thisKeys = nodeToKeys.get(key);
			if (thisKeys != null && thisKeys.size() > 0) {
				ret += delete(key, getBArrArr(thisKeys));
			}
		}
		return ret;
	}

	private long delete(String shardingKey, String key, byte[]... bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				long ret = jedis.del(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0;
	}

	private long delete(String key, byte[]... bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				long ret = jedis.del(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0;
	}
	

	/******************************** above:delete,multidelete *****************************/

	/******************************* below:inc ******************************************/
	/**
	 * 对key做自增1。<br/>
	 * 如果key本不存在，则在执行此操作前设置默认值为0<br/>
	 * 如果key存在，且key是十进制数值的字符串表示(e.g: "-123")，则在些数据基础上自增(e.g:return -122L)<br/>
	 * 如果key存在，且key不是十进制数值的字符串表示，则返回null
	 * 
	 * @param key
	 * @return 自增后的Long值。如果操作失败返回null
	 */

	public Long incr(String key) {
		return incrBy(key, 1);
	}

	/**
	 * 类似于incr(key).此方法可设置自增步长
	 * 
	 * @param key
	 * @param step
	 * @return 自增后的Long值.如果操作失败返回null
	 */

	public Long incrBy(String key, long step) {
		return incrBy(key, SafeEncoder.encode(key), step);
	}
	
	public Double incrByFloat(String key, float step){
		return incrByFloat(key, SafeEncoder.encode(key), step);
	}
	
	private Double incrByFloat(String key, byte[] bytekey, float step) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Double ret = jedis.incrByFloat(bytekey, step);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	private Long incrBy(String key, byte[] bytekey, long step) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.incrBy(bytekey, step);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * 取得记录incr或desr的当前值
	 * 
	 * @param key
	 * @return null表示不存在,数值表示此key的当前值
	 */

	public Long getNumberRecordIncrOrDesr(String key) {
		String ret = getString(key);
		if (ret != null) {
			try {
				long num = Long.parseLong(ret);
				return num;
			} catch (Exception e) {
				return null;
			}
		}
		return null;
	}

	/******************************** above:inc ********************************************/

	/******************************* below:desr ********************************************/
	/**
	 * 对key做自减1。<br/>
	 * 如果key本不存在，则在执行此操作前设置默认值为0 如果key存在，且key是十进制数值的字符串表示(e.g:
	 * "-123")，则在些数据基础上自减(e.g:return -124L)<br/>
	 * 如果key存在，且key不是十进制数值的字符串表示，则返回null
	 * 
	 * @param key
	 * @return 自减后的Long值，可为负数。如果操作失败返回null
	 */

	public Long decr(String key) {
		return decrBy(key, 1);
	}

	/**
	 * 类似于decr(key).此方法可设置自减步长
	 * 
	 * @param key
	 * @param step
	 * @return 自减后的Long值.如果操作失败返回null
	 */

	public Long decrBy(String key, long step) {

		return decrBy(key, SafeEncoder.encode(key), step);

	}

	private Long decrBy(String key, byte[] bytekey, long step) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.decrBy(bytekey, step);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/******************************** above:desc ********************************************/

	/******************************* below:append ***************************************/
	/**
	 * 对原value后进行数据追加
	 * 
	 * @param key
	 * @param appendStr
	 * @return 追加后的value总字节数
	 */

	public Long append(String key, String appendStr) {
		return append(key, SafeEncoder.encode(appendStr));
	}

	/**
	 * 对原value后进行数据追加
	 * 
	 * @param key
	 * @param appendBytes
	 * @return 追加后的value总字节数
	 */

	public Long append(String key, byte[] appendBytes) {
		valueTypeAssert(appendBytes);

		return append(key, SafeEncoder.encode(key), appendBytes);

	}

	private Long append(String key, byte[] bytekey, byte[] appendBytes) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.append(bytekey, appendBytes);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/******************************** above:append ***************************************/

	/******************************** below:getSet ***************************************/
	/**
	 * set a new str-value, and return the old str-value
	 * 
	 * @param key
	 * @param expireSecond
	 * @param value
	 * @return
	 */

	public String getSetString(String key, int expireSecond, String value) {
		valueTypeAssert(value);

		byte[] ret = getSet(key, SafeEncoder.encode(key), expireSecond,
				SafeEncoder.encode(value));
		if (ret != null) {
			return SafeEncoder.encode(ret);
		}
		return null;
	}

	/**
	 * set a new Object-value, and return a old Object-value
	 * 
	 * @param key
	 * @param expireSecond
	 * @param value
	 * @return
	 */

	public Object getSetObject(String key, int expireSecond, Object value) {
		valueTypeAssert(value);

		byte[] ret = getSet(key, SafeEncoder.encode(key), expireSecond,
				serialize(value));
		if (ret != null) {
			return deserialize(ret);
		}

		return null;
	}

	/**
	 * set a new [B-value, and return a old [B-value
	 * 
	 * @param key
	 * @param expireSecond
	 * @param value
	 * @return
	 */

	public byte[] getSetByteArr(String key, int expireSecond, byte[] value) {
		valueTypeAssert(value);
		return getSet(key, SafeEncoder.encode(key), expireSecond, value);

	}

	private byte[] getSet(String key, byte[] bytekey, int expireSecond,
			byte[] value) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				byte[] ret = jedis.getSet(bytekey, value);
				if (expireSecond > 0) {
					jedis.expire(bytekey, expireSecond);
				}
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/******************************** above:getSet ***************************************/

	/******************************* below:hash hSet ************************************/
	/**
	 * 增加或更新hashmap的某一数据项（String类型）。<br/>
	 * 不可针对某数据项单独设置过期时间，可对整个hashmap使用expire(key,time)设置过期时间
	 * 
	 * @param key
	 * @param field
	 * @param value
	 * @return 0 成功更新数据项，1成功新数据项，-1操作失败
	 */

	public long hSetString(String key, String field, String value) {
		valueTypeAssert(value);

		return hSet(key, SafeEncoder.encode(key), SafeEncoder.encode(field),
				SafeEncoder.encode(value));

	}

	/**
	 * 增加或更新hashmap的某一数据项（Object）。<br/>
	 * 不可针对某数据项单独设置过期时间，可对整个hashmap使用expire(key,time)设置过期时间
	 * 
	 * @param key
	 * @param field
	 * @param value
	 * @return 0 成功更新数据项，1成功新数据项，-1操作失败
	 */

	public long hSetObject(String key, String field, Object value) {
		valueTypeAssert(value);

		return hSet(key, SafeEncoder.encode(key), SafeEncoder.encode(field),
				serialize(value));

	}

	/**
	 * 增加或更新hashmap的某一数据项（byte[]数据块）。<br/>
	 * 不可针对某数据项单独设置过期时间，可对整个hashmap使用expire(key,time)设置过期时间
	 * 
	 * @param key
	 * @param field
	 * @param value
	 * @return 0 成功更新数据项，1成功新数据项，-1操作失败
	 */

	public long hSetByteArr(String key, String field, byte[] value) {
		valueTypeAssert(value);

		return hSet(key, SafeEncoder.encode(key), SafeEncoder.encode(field),
				value);

	}

	private long hSet(String key, byte[] bytekey, byte[] field, byte[] value) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.hset(bytekey, field, value);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return -1L;
	}

	/******************************** above:hash hSet ***************************************/

	/******************************* below:hash hMultiSet ***************************************/
	/**
	 * 同时更新某hashmap下的若干个数据项（String）。<br/>
	 * 不可针对某数据项单独设置过期时间，可对整个hashmap使用expire(key,time)设置过期时间
	 * 
	 * @param key
	 * @param fieldValues
	 * @return "OK" 更新成功，“failed”失败
	 */

	public String hMultiSetString(String key, Map<String, String> fieldValues) {
		Map<byte[], byte[]> fieldbValuebMap = new HashMap<byte[], byte[]>();
		for (String field : fieldValues.keySet()) {
			String value = fieldValues.get(field);
			if (value != null) {
				fieldbValuebMap.put(SafeEncoder.encode(field),
						SafeEncoder.encode(value));
			}
		}
		return hMultiSet(key, fieldbValuebMap);
	}

	/**
	 * 同时更新某hashmap下的若干个数据项（Object）。<br/>
	 * 不可针对某数据项单独设置过期时间，可对整个hashmap使用expire(key,time)设置过期时间
	 * 
	 * @param key
	 * @param fieldValues
	 * @return "OK" 更新成功，“failed”失败
	 */

	public String hMultiSetObject(String key, Map<String, Object> fieldValues) {
		Map<byte[], byte[]> fieldbValuebMap = new HashMap<byte[], byte[]>();
		for (String field : fieldValues.keySet()) {
			Object value = fieldValues.get(field);
			if (value != null) {
				fieldbValuebMap
						.put(SafeEncoder.encode(field), serialize(value));
			}
		}
		return hMultiSet(key, fieldbValuebMap);
	}

	/**
	 * 同时更新某hasmap下的若干个数据项（byte[]数据块）。<br/>
	 * 不可针对某数据项单独设置过期时间，可对整个hashmap使用expire(key,time)设置过期时间
	 * 
	 * @param key
	 * @param fieldValues
	 * @return "OK" 更新成功，“failed”失败
	 */

	public String hMultiSetByteArr(String key, Map<String, byte[]> fieldValues) {
		Map<byte[], byte[]> fieldbValuebMap = new HashMap<byte[], byte[]>();
		for (String field : fieldValues.keySet()) {
			byte[] value = fieldValues.get(field);
			if (value != null) {
				fieldbValuebMap.put(SafeEncoder.encode(field), value);
			}
		}
		return hMultiSet(key, fieldbValuebMap);
	}

	private String hMultiSet(String key, Map<byte[], byte[]> fieldbValuebMap) {

		return hMultiSet(key, SafeEncoder.encode(key), fieldbValuebMap);

	}

	private String hMultiSet(String key, byte[] bytekey,
			Map<byte[], byte[]> hash) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				String ret = jedis.hmset(bytekey, hash);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return "failed";
	}

	/******************************** above:hash hMultiSet ***************************************/

	/******************************* below:hash hGet ***************************************/
	/**
	 * 以字符串方式取出某hashmap下的某数据项
	 * 
	 * @param key
	 * @param field
	 * @return
	 */

	public String hGetString(String key, String field) {
		byte[] ret = hGetByteArr(key, field);
		if (ret != null) {
			return SafeEncoder.encode(ret);
		}
		return null;
	}

	/**
	 * 以Object方式取出某hashmap下的某数据项
	 * 
	 * @param key
	 * @param field
	 * @return
	 */

	public Object hGetObject(String key, String field) {
		byte[] ret = hGetByteArr(key, field);
		if (ret != null) {
			return deserialize(ret);
		}
		return null;
	}

	/**
	 * 以数据块的方式 取出某hashmap下的某数据项
	 * 
	 * @param key
	 * @param field
	 * @return
	 */

	public byte[] hGetByteArr(String key, String field) {

		return hGet(key, SafeEncoder.encode(key), SafeEncoder.encode(field));

	}

	private byte[] hGet(String key, byte[] bytekey, byte[] field) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				byte[] ret = jedis.hget(bytekey, field);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/******************************** above:hash hGet ***************************************/

	/******************************* below:hash hGetAll ***************************************/
	/**
	 * 以字符串的方式 取出某hashmap下的所有数据项
	 * 
	 * @param key
	 * @return
	 */

	public Map<String, String> hGetAllString(String key) {
		Map<String, byte[]> temp = hGetAllByteArr(key);
		if (temp != null) {
			Map<String, String> ret = new HashMap<String, String>();
			for (String field : temp.keySet()) {
				byte[] value = temp.get(field);
				if (value != null) {
					ret.put(field, SafeEncoder.encode(temp.get(field)));
				}
			}
			return ret;
		}
		return null;
	}

	/**
	 * 以Object的方式 取出某hashmap下的所有数据项
	 * 
	 * @param key
	 * @return
	 */

	public Map<String, Object> hGetAllObject(String key) {
		Map<String, byte[]> temp = hGetAllByteArr(key);
		if (temp != null) {
			Map<String, Object> ret = new HashMap<String, Object>();
			for (String field : temp.keySet()) {
				byte[] value = temp.get(field);
				if (value != null) {
					ret.put(field, deserialize(temp.get(field)));
				}
			}
			return ret;
		}
		return null;
	}

	/**
	 * 以数据块的方式 取出某hashmap下的所有数据项
	 * 
	 * @param key
	 * @return
	 */

	public Map<String, byte[]> hGetAllByteArr(String key) {

		return hGetAll(key, SafeEncoder.encode(key));

	}

	private Map<String, byte[]> hGetAll(String key, byte[] bytekey) {
		Map<String, byte[]> map = new HashMap<String, byte[]>();
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Map<byte[], byte[]> ret = jedis.hgetAll(bytekey);
				for (Map.Entry<byte[], byte[]> item : ret.entrySet()) {
					map.put(SafeEncoder.encode(item.getKey()), item.getValue());
				}
				return map;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/******************************** above:hash hGetAll ***************************************/

	/******************************* below:hash hMultiGet **************************************/
	/**
	 * 以字符串的方式 取出某hashmap下的多个数据项
	 * 
	 * @param key
	 * @param fields
	 * @return
	 */

	public Map<String, String> hMultiGetString(String key, List<String> fields) {
		Map<String, byte[]> temp = hMultiGetByteArr(key, fields);
		if (temp != null) {
			Map<String, String> ret = new HashMap<String, String>();
			for (String field : temp.keySet()) {
				byte[] value = temp.get(field);
				if (value != null) {
					ret.put(field, SafeEncoder.encode(temp.get(field)));
				}
			}
			return ret;
		}
		return null;
	}

	/**
	 * 以Object的方式 取出某hashmap下的多个数据项
	 * 
	 * @param key
	 * @param fields
	 * @return
	 */

	public Map<String, Object> hMultiGetObject(String key, List<String> fields) {
		Map<String, byte[]> temp = hMultiGetByteArr(key, fields);
		if (temp != null) {
			Map<String, Object> ret = new HashMap<String, Object>();
			for (String field : temp.keySet()) {
				byte[] value = temp.get(field);
				if (value != null) {
					ret.put(field, deserialize(temp.get(field)));
				}
			}
			return ret;
		}
		return null;
	}

	/**
	 * 以byte[]数据块的方式 取出某hashmap下的多个数据项
	 * 
	 * @param key
	 * @param fields
	 * @return
	 */

	public Map<String, byte[]> hMultiGetByteArr(String key, List<String> fields) {

		return hMultiGet(key, SafeEncoder.encode(key), getBArrArr(fields));

	}

	private Map<String, byte[]> hMultiGet(String key, byte[] bytekey,
			byte[]... fields) {
		Map<String, byte[]> map = new HashMap<String, byte[]>();
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				List<byte[]> ret = jedis.hmget(bytekey, fields);
				for (int i = ret.size() - 1; i >= 0; i--) {
					map.put(SafeEncoder.encode(fields[i]), ret.get(i));
				}
				return map;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return map;
	}

	/******************************** above:hash hMultiGet ***************************************/

	/******************************* below:hash hSetIfNotExist ***************************************/
	/**
	 * 类似于hSetString，但只有在field不存在时才设置
	 * 
	 * @param key
	 * @param field
	 * @param value
	 * @return -1操作失败；0 field已存在，本次设置不成功; 1 field不存在，设置成功
	 */

	public long hSetStringIfNotExist(String key, String field, String value) {
		return hSetByteArrIfNotExist(key, field, SafeEncoder.encode(value));
	}

	/**
	 * 类似于hSetObject，但只有在field不存在时才设置
	 * 
	 * @param key
	 * @param field
	 * @param value
	 * @return -1操作失败；0 field已存在，本次设置不成功; 1 field不存在，设置成功
	 */

	public long hSetObjectIfNotExist(String key, String field, Object value) {
		return hSetByteArrIfNotExist(key, field, serialize(value));
	}

	/**
	 * 类似于hSetByteArr，但只有在field不存在时才设置
	 * 
	 * @param key
	 * @param field
	 * @param value
	 * @return -1操作失败；0 field已存在，本次设置不成功; 1 field不存在，设置成功
	 */

	public long hSetByteArrIfNotExist(String key, String field, byte[] value) {
		valueTypeAssert(value);

		return hSetIfNotExist(key, SafeEncoder.encode(key),
				SafeEncoder.encode(field), value);

	}

	private long hSetIfNotExist(String key, byte[] bytekey, byte[] field,
			byte[] value) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.hsetnx(bytekey, field, value);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return -1L;
	}

	/******************************** above:hash setInNotExist ***************************************/

	/******************************* below:hash hLen,hKeys,hDel,hIncrBy,hExists ************************/
	/**
	 * 删除某hashmap的某项
	 * 
	 * @param key
	 * @param field
	 * @return 1 删除成功；0 field 不存在，删除不成功;-1服务端异常
	 */

	public long hDelete(String key, String field) {

		return hDelete(key, SafeEncoder.encode(key), SafeEncoder.encode(field));

	}

	private long hDelete(String key, byte[] bytekey, byte[] field) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				long ret = jedis.hdel(bytekey, field);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return -1;
	}

	/**
	 * 获取某hashmap中的items数
	 * 
	 * @param key
	 * @return
	 */

	public long hLen(String key) {

		return hLen(key, SafeEncoder.encode(key));

	}

	private long hLen(String key, byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				long ret = jedis.hlen(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0;
	}

	public Set<String> hKeys(String key) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Set<String> ret = jedis.hkeys(key);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * 对hashmap下的某field进行自增操作。自增规则可见incr()接口
	 * 
	 * @param key
	 * @param field
	 * @param step
	 *            自增步长，可为负数
	 * @return 自增后的新值。如果原值为十进制的字符串表示，则返回null
	 */

	public Long hIncrBy(String key, String field, long step) {

		return hIncrBy(key, SafeEncoder.encode(key), SafeEncoder.encode(field),
				step);

	}

	private Long hIncrBy(String key, byte[] bytekey, byte[] field, long step) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.hincrBy(bytekey, field, step);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * 判断某hashmap下是否包含某field
	 * 
	 * @param key
	 * @param field
	 * @return
	 */

	public Boolean hExists(String key, String field) {

		return hExists(key, SafeEncoder.encode(key), SafeEncoder.encode(field));

	}

	private Boolean hExists(String key, byte[] bytekey, byte[] field) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Boolean ret = jedis.hexists(bytekey, field);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return false;
	}

	/******************************** above:hash hLen,hKeys,hDel,hIncrBy,hExists ************************/

	/****************** below:list lpush,rpush,lpushIfListExist,rpushIfListExist ***********************/
	/**
	 * 在list左端新增String类型的item
	 * 
	 * @param key
	 * @param item
	 * @return 操作完成后的list长度
	 */

	public Long lpushString(String key, String item) {
		return lpushByteArr(key, SafeEncoder.encode(item));
	}

	/**
	 * 在list左端新增Object类型的item
	 * 
	 * @param key
	 * @param item
	 * @return 操作完成后的list长度
	 */

	public Long lpushObject(String key, Object item) {
		return lpushByteArr(key, serialize(item));
	}

	/**
	 * 在list左端新增byte[]类型的item
	 * 
	 * @param key
	 * @param item
	 * @return 操作完成后的list长度
	 */

	public Long lpushByteArr(String key, byte[] item) {
		valueTypeAssert(item);
		return lpush(key, SafeEncoder.encode(key), item);
	}

	private Long lpush(String key, byte[] bytekey, byte[] value) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.lpush(bytekey, value);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/**
	 * 在list右端新增String类型的item
	 * 
	 * @param key
	 * @param item
	 * @return 操作完成后的list长度
	 */

	public Long rpushString(String key, String item) {
		return rpushByteArr(key, SafeEncoder.encode(item));
	}

	/**
	 * 在list右端新增Object类型的item
	 * 
	 * @param key
	 * @param item
	 * @return 操作完成后的list长度
	 */

	public Long rpushObject(String key, Object item) {
		return rpushByteArr(key, serialize(item));
	}

	/**
	 * 在list右端新增byte[]类型的item
	 * 
	 * @param key
	 * @param item
	 * @return 操作完成后的list长度
	 */

	public Long rpushByteArr(String key, byte[] item) {
		valueTypeAssert(item);

		return rpush(key, SafeEncoder.encode(key), item);

	}

	private Long rpush(String key, byte[] bytekey, byte[] value) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.rpush(bytekey, value);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	public Long lpushStringIfListExist(String key, String item) {
		return lpushByteArrIfListExist(key, SafeEncoder.encode(item));
	}

	public Long lpushObjectIfListExist(String key, Object item) {
		return lpushByteArrIfListExist(key, serialize(item));
	}

	public Long lpushByteArrIfListExist(String key, byte[] item) {
		valueTypeAssert(item);

		return lpushIfListExist(key, SafeEncoder.encode(key), item);

	}

	private Long lpushIfListExist(String key, byte[] bytekey, byte[] value) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.lpushx(bytekey, value);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	public Long rpushStringIfListExist(String key, String item) {
		return rpushByteArrIfListExist(key, SafeEncoder.encode(item));
	}

	public Long rpushObjectIfListExist(String key, Object item) {
		return rpushByteArrIfListExist(key, serialize(item));
	}

	public Long rpushByteArrIfListExist(String key, byte[] item) {
		valueTypeAssert(item);

		return rpushIfListExist(key, SafeEncoder.encode(key), item);

	}

	private Long rpushIfListExist(String key, byte[] bytekey, byte[] value) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.rpushx(bytekey, value);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/******************** above:list lpush,rpush,lpushIfListExist,rpushIfListExist ***********************/

	/******************************* below:list lpop,rpop ***************************************/
	/**
	 * 在list的最左端以String的方式，取出并删除一个item
	 * 
	 * @param key
	 * @return
	 */

	public String lpopString(String key) {
		byte[] ret = lpopByteArr(key);
		if (ret != null) {
			return SafeEncoder.encode(ret);
		}
		return null;
	}

	/**
	 * 在list的最左端以Object的方式，取出并删除一个item
	 * 
	 * @param key
	 * @return
	 */

	public Object lpopObject(String key) {
		byte[] ret = lpopByteArr(key);
		if (ret != null) {
			return deserialize(ret);
		}
		return null;
	}

	/**
	 * 在list的最左端以byte[]的方式，取出并删除一个item
	 * 
	 * @param key
	 * @return
	 */

	public byte[] lpopByteArr(String key) {

		return lpop(key, SafeEncoder.encode(key));

	}

	private byte[] lpop(String key, byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				byte[] ret = jedis.lpop(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * 在list的最右端以String的方式，取出并删除一个item
	 * 
	 * @param key
	 * @return
	 */

	public String rpopString(String key) {
		byte[] ret = rpopByteArr(key);
		if (ret != null) {
			return SafeEncoder.encode(ret);
		}
		return null;
	}

	/**
	 * 在list的最右端以Object的方式，取出并删除一个item
	 * 
	 * @param key
	 * @return
	 */

	public Object rpopObject(String key) {
		byte[] ret = rpopByteArr(key);
		if (ret != null) {
			return deserialize(ret);
		}
		return null;
	}

	/**
	 * 在list的最右端以byte[]的方式，取出并删除一个item
	 * 
	 * @param key
	 * @return
	 */

	public byte[] rpopByteArr(String key) {

		return rpop(key, SafeEncoder.encode(key));

	}

	private byte[] rpop(String key, byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				byte[] ret = jedis.rpop(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/******************************** above:list lpop,rpop ***************************************/

	/******************************* below:list lindex,lrange *************************************/
	/**
	 * 以String的方式取出list的index（从左到右从0开始计数）位上item
	 * 
	 * @param key
	 * @return
	 */

	public String lindexString(String key, int index) {
		byte[] ret = lindexByteArr(key, index);
		if (ret != null) {
			return SafeEncoder.encode(ret);
		}
		return null;
	}

	/**
	 * 以Object的方式取出list的index（从左到右从0开始计数）位上item
	 * 
	 * @param key
	 * @return
	 */

	public Object lindexObject(String key, int index) {
		byte[] ret = lindexByteArr(key, index);
		if (ret != null) {
			return deserialize(ret);
		}
		return null;
	}

	/**
	 * 以byte[]的方式取出list的index（从左到右从0开始计数）位上item
	 * 
	 * @param key
	 * @return
	 */

	public byte[] lindexByteArr(String key, int index) {

		return lindex(key, SafeEncoder.encode(key), index);

	}

	private byte[] lindex(String key, byte[] bytekey, int index) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				byte[] ret = jedis.lindex(bytekey, index);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * 以String的方式取出list的某位置区间上的items。
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */

	public List<String> lrangeString(String key, int start, int end) {
		List<byte[]> ret = lrangeByteArr(key, start, end);
		if (ret != null) {
			List<String> trueRet = new ArrayList<String>();
			for (byte[] item : ret) {
				if (item != null) {
					trueRet.add(SafeEncoder.encode(item));
				}
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 以Object的方式取出list的某位置区间上的items
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */

	public List<Object> lrangeObject(String key, int start, int end) {
		List<byte[]> ret = lrangeByteArr(key, start, end);
		if (ret != null) {
			List<Object> trueRet = new ArrayList<Object>();
			for (byte[] item : ret) {
				if (item != null) {
					trueRet.add(deserialize(item));
				}
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 以byte[]的方式取出list的某位置区间上的items
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return
	 */

	public List<byte[]> lrangeByteArr(String key, int start, int end) {

		return lrange(key, SafeEncoder.encode(key), start, end);

	}

	private List<byte[]> lrange(String key, byte[] bytekey, int start, int end) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				List<byte[]> ret = jedis.lrange(bytekey, start, end);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/******************************** above:list lindex,lrange ***************************************/

	/******************************* below:list lset,ltrim ***************************************/
	/**
	 * 设置list的index位置上的值（String类型）
	 * 
	 * @param key
	 * @param index
	 * @param value
	 * @return 如果index超出list长度返回failed;否则设置成功返回OK
	 */

	public String lsetString(String key, int index, String value) {
		return lsetByteArr(key, index, SafeEncoder.encode(value));
	}

	/**
	 * 设置list的index位置上的值（Object类型）
	 * 
	 * @param key
	 * @param index
	 * @param value
	 * @return 如果index超出list长度返回failed;否则设置成功返回OK
	 */

	public String lsetObject(String key, int index, Object value) {
		return lsetByteArr(key, index, serialize(value));
	}

	/**
	 * 设置list的index位置上的值（byte[]类型）
	 * 
	 * @param key
	 * @param index
	 * @param value
	 * @return 如果index超出list长度返回failed;否则设置成功返回OK
	 */

	public String lsetByteArr(String key, int index, byte[] value) {
		valueTypeAssert(value);

		return lset(key, SafeEncoder.encode(key), index, value);

	}

	private String lset(String key, byte[] bytekey, int index, byte[] value) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				String ret = jedis.lset(bytekey, index, value);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return "failed";
	}

	/**
	 * 对list在服务端进行截取，范围之外部分将被服务端永久丢弃
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return 截取成功返回OK；如果指定范围超出list的实际范围，返回failed
	 */

	public String ltrim(String key, int start, int end) {

		return ltrim(key, SafeEncoder.encode(key), start, end);

	}

	private String ltrim(String key, byte[] bytekey, int start, int end) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				String ret = jedis.ltrim(bytekey, start, end);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return "failed";
	}

	/******************************** above:list lset,ltrim ***************************************/

	/******************************* below:list len ***************************************/
	/**
	 * 获取某list的长度
	 * 
	 * @param key
	 * @return
	 */

	public Long llen(String key) {

		return llen(key, SafeEncoder.encode(key));

	}

	private Long llen(String key, byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.llen(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/******************************** above:list len ***************************************/

	/******************************* below:set sadd,srem,spop,smember **********************/
	/**
	 * 往集合中插入member
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long saddString(String key, String member) {
		return saddByteArr(key, SafeEncoder.encode(member));
	}

	/**
	 * 往集合中插入member(复杂对象是否适应于此方法有待测试验证)
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long saddObject(String key, Object member) {
		return saddByteArr(key, serialize(member));
	}

	/**
	 * 往集合中插入member
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long saddByteArr(String key, byte[] member) {
		valueTypeAssert(member);

		return sadd(key, SafeEncoder.encode(key), member);

	}

	private Long sadd(String key, byte[] bytekey, byte[] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.sadd(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/******************************* below:set sadd,srem,spop,smember **********************/
	/**
	 * 往集合中插入member
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long smultiAddString(String key, String... members) {
		return smultiAddByteArr(key, SafeEncoder.encodeMany(members));
	}

	/**
	 * 往集合中插入member(复杂对象是否适应于此方法有待测试验证)
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long smultiAddObject(String key, Object... members) {
		return smultiAddByteArr(key, serialize(members));
	}

	/**
	 * 往集合中插入member
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long smultiAddByteArr(String key, byte[][] members) {
		valueTypeAssert(members);

		return smultiAdd(key, SafeEncoder.encode(key), members);

	}

	private Long smultiAdd(String key, byte[] bytekey, byte[][] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.sadd(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/**
	 * 删除集合中的member成员
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was removed 0
	 *         if the new element was not a member of the set
	 */

	public Long sremString(String key, String member) {
		return sremByteArr(key, SafeEncoder.encode(member));
	}

	/**
	 * 删除集合中的member成员（复杂对象是否适合此方法有待测试）
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was removed 0
	 *         if the new element was not a member of the set
	 */

	public Long sremObject(String key, Object member) {
		return sremByteArr(key, serialize(member));
	}

	/**
	 * 删除集合中的member成员
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was removed 0
	 *         if the new element was not a member of the set
	 */

	public Long sremByteArr(String key, byte[] member) {
		valueTypeAssert(member);

		return srem(key, SafeEncoder.encode(key), member);

	}

	private Long srem(String key, byte[] bytekey, byte[] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.srem(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/**
	 * Remove and return a random member from a set
	 * 
	 * @param key
	 * @return
	 */

	public String spopString(String key) {
		byte[] ret = spopByteArr(key);
		if (ret != null) {
			return SafeEncoder.encode(ret);
		}
		return null;
	}

	/**
	 * Remove and return a random member from a set
	 * 
	 * @param key
	 * @return
	 */

	public Object spopObject(String key) {
		byte[] ret = spopByteArr(key);
		if (ret != null) {
			return deserialize(ret);
		}
		return null;
	}

	/**
	 * Remove and return a random member from a set
	 * 
	 * @param key
	 * @return
	 */

	public byte[] spopByteArr(String key) {

		return spop(key, SafeEncoder.encode(key));

	}

	private byte[] spop(String key, byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				byte[] ret = jedis.spop(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * Get all the members in a set
	 * 
	 * @param key
	 * @return
	 */

	public Set<String> smemberString(String key) {
		Set<byte[]> ret = smemberByteArr(key);
		if (ret != null) {
			Set<String> trueRet = new HashSet<String>();
			for (byte[] member : ret) {
				if (member != null) {
					trueRet.add(SafeEncoder.encode(member));
				}
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * Get all the members in a set
	 * 
	 * @param key
	 * @return
	 */

	public Set<Object> smemberObject(String key) {
		Set<byte[]> ret = smemberByteArr(key);
		if (ret != null) {
			Set<Object> trueRet = new HashSet<Object>();
			for (byte[] member : ret) {
				if (member != null) {
					trueRet.add(deserialize(member));
				}
			}
			return trueRet;
		}
		return null;
	}
	
	public Set<Object> sRandMemberObject(String key, int count) {
		
		byte[] bytekey = SafeEncoder.encode(key);
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			if (jedis != null) {
				List<byte[]> ret = jedis.srandmember(bytekey, count);
				
				if (ret != null) {
					Set<Object> trueRet = new HashSet<Object>();
					for (byte[] member : ret) {
						if (member != null) {
							trueRet.add(deserialize(member));
						}
					}
					return trueRet;
				}
				
				
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * Get all the members in a set
	 * 
	 * @param key
	 * @return
	 */

	public Set<byte[]> smemberByteArr(String key) {

		return smember(key, SafeEncoder.encode(key));

	}

	private Set<byte[]> smember(String key, byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Set<byte[]> ret = jedis.smembers(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/******************************** above:set sadd,srem,spop,smember *************************/

	/******************************* below:set scard,sismember *******************************/
	/**
	 * 判断某个member是否在此集合中
	 * 
	 * @param key
	 * @param member
	 * @return
	 */

	public Boolean sismemberString(String key, String member) {
		return sismemberByteArr(key, SafeEncoder.encode(member));
	}

	/**
	 * 判断某个member是否在此集合中
	 * 
	 * @param key
	 * @param member
	 * @return
	 */

	public Boolean sismemberObject(String key, Object member) {
		return sismemberByteArr(key, serialize(member));
	}

	/**
	 * 判断某个member是否在此集合中
	 * 
	 * @param key
	 * @param member
	 * @return
	 */

	public Boolean sismemberByteArr(String key, byte[] member) {
		if (member == null) {
			return false;
		}

		return sismember(key, SafeEncoder.encode(key), member);

	}

	private Boolean sismember(String key, byte[] bytekey, byte[] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Boolean ret = jedis.sismember(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return false;
	}

	/**
	 * Get the number of members in a set
	 * 
	 * @param key
	 * @return
	 */

	public Long scard(String key) {

		return scard(key, SafeEncoder.encode(key));

	}

	private Long scard(String key, byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.scard(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/******************************** above:set scard,sismember *******************************/
	
	

	/**
	 * <pre>
	 * 目前只支持单节点redis
	 * Return the members of a set resulting from the union of all the sets hold at the specified keys.
	 * </pre>
	 * @param keys
	 * @return
	 */
	public Set<String> sunion(String... keys) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(keys[0]);
			if (jedis != null) {
				Set<String> ret = jedis.sunion(keys);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage() + jedis.getClient().getHost() + ":" + jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}
	
	
	

	/****************************** below: set sinter，sinterstore *************************/

	/****************************** above: set sinter，sinterstore *************************/

	/****************************** below:sorted set ZADD、zaddMulti *************************/
	/**
	 * Add the specified member having the specifeid score to the sorted set
	 * stored at key. If member is already a member of the sorted set the score
	 * is updated, and the element reinserted in the right position to ensure
	 * sorting. If key does not exist a new sorted set with the specified member
	 * as sole member is created. If the key exists but does not hold a sorted
	 * set value an error is returned.
	 * <p>
	 * The score value can be the string representation of a double precision
	 * floating point number.
	 * <p>
	 * Time complexity O(log(N)) with N being the number of elements in the
	 * sorted set
	 * 
	 * @param key
	 * @param score
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added; 0 if
	 *         the element was already a member of the sorted set and the score
	 *         was updated ; -1 the error happened in server
	 */

	public Long zaddStringWithSharding(String shardingKey, String key,
			double score, String member) {
		return zaddByteArrWithSharding(shardingKey, key, score,
				SafeEncoder.encode(member));
	}

	public Long zaddObjectWithSharding(String shardingKey, String key,
			double score, Object member) {
		return zaddByteArrWithSharding(shardingKey, key, score,
				serialize(member));
	}

	public Long zaddByteArrWithSharding(String shardingKey, String key,
			double score, byte[] member) {
		valueTypeAssert(member);

		return zaddWithSharding(shardingKey, key, SafeEncoder.encode(key),
				score, member);

	}

	private Long zaddWithSharding(String shardingKey, String key,
			byte[] bytekey, double score, byte[] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zadd(bytekey, score, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/**
	 * 往sorted set中插入多个元素
	 * 
	 * @param key
	 * @param scoreMembers
	 * @return 成功插入元素的个数
	 */

	public Long zaddMultiStringWithSharding(String shardingKey, String key,
			Map<Double, String> scoreMembers) {
		Map<Double, byte[]> scoreBMembers = new HashMap<Double, byte[]>();
		for (Map.Entry<Double, String> item : scoreMembers.entrySet()) {
			if (item.getValue() != null) {
				scoreBMembers.put(item.getKey(),
						SafeEncoder.encode(item.getValue()));
			}
		}
		return zaddMultiByteArrWithSharding(shardingKey, key, scoreBMembers);
	}

	/**
	 * 往sorted set中插入多个元素
	 * 
	 * @param key
	 * @param scoreMembers
	 * @return 成功插入元素的个数
	 */

	public Long zaddMultiObjectWithSharding(String shardingKey, String key,
			Map<Double, Object> scoreMembers) {
		Map<Double, byte[]> scoreBMembers = new HashMap<Double, byte[]>();
		for (Map.Entry<Double, Object> item : scoreMembers.entrySet()) {
			if (item.getValue() != null) {
				scoreBMembers.put(item.getKey(), serialize(item.getValue()));
			}
		}
		return zaddMultiByteArrWithSharding(shardingKey, key, scoreBMembers);
	}

	/**
	 * 往sorted set中插入多个元素
	 * 
	 * @param key
	 * @param scoreMembers
	 * @return 成功插入元素的个数
	 */

	public Long zaddMultiByteArrWithSharding(String shardingKey, String key,
			Map<Double, byte[]> scoreMembers) {
		if (scoreMembers == null || scoreMembers.size() == 0) {
			return 0L;
		}

		return zaddWithSharding(shardingKey, key, SafeEncoder.encode(key),
				scoreMembers);

	}

	private Long zaddWithSharding(String shardingKey, String key,
			byte[] bytekey, Map<Double, byte[]> scoreMembers) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zadd(bytekey, scoreMembers);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/****************************** above:sorted set ZADD、zaddMulti *************************/

	/****************************** above:sorted set zremrangeByRank、 ZREM、zremMulti *************************/
	/**
	 * 从有序集合中删除指定位置范围元素
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return 所删除的元素个数
	 */

	public Long zremrangeByRankWithSharding(String shardingKey, String key,
			int start, int end) {

		return zremrangeByRankWithSharding(shardingKey, key,
				SafeEncoder.encode(key), start, end);

	}

	private Long zremrangeByRankWithSharding(String shardingKey, String key,
			byte[] bytekey, int start, int end) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zremrangeByRank(bytekey, start, end);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/**
	 * 从有序集合中删除指定元素
	 * 
	 * @param key
	 * @param member
	 * @return 0，未找到该元素删除不成功； 1，找到并删除成功
	 */

	public Long zremStringWithSharding(String shardingKey, String key,
			String member) {
		return zremByteArrWithSharding(shardingKey, key,
				SafeEncoder.encode(member));
	}

	/**
	 * 从有序集合中删除指定元素
	 * 
	 * @param key
	 * @param member
	 * @return 0，未找到该元素删除不成功； 1，找到并删除成功
	 */

	public Long zremObjectWithSharding(String shardingKey, String key,
			Object member) {
		return zremByteArrWithSharding(shardingKey, key, serialize(member));
	}

	/**
	 * 从有序集合中删除指定元素
	 * 
	 * @param key
	 * @param member
	 * @return 0，未找到该元素删除不成功； 1，找到并删除成功
	 */

	public Long zremByteArrWithSharding(String shardingKey, String key,
			byte[] member) {
		if (member == null) {
			return 0L;
		}

		return zremWithSharding(shardingKey, key, SafeEncoder.encode(key),
				member);

	}

	/**
	 * 从有序集合中删除多个指定元素
	 * 
	 * @param key
	 * @param memberList
	 * @return 成功删除的元素个数
	 */

	public Long zremMultiStringWithSharding(String shardingKey, String key,
			List<String> memberList) {
		List<byte[]> bArrList = new ArrayList<byte[]>();
		for (String member : memberList) {
			if (member != null) {
				bArrList.add(SafeEncoder.encode(member));
			}
		}
		return zremMultiByteArrWithSharding(shardingKey, key, bArrList);
	}

	/**
	 * 从有序集合中删除多个指定元素
	 * 
	 * @param key
	 * @param memberList
	 * @return 成功删除的元素个数
	 */

	public Long zremMultiObjectWithSharding(String shardingKey, String key,
			List<Object> memberList) {
		List<byte[]> bArrList = new ArrayList<byte[]>();
		for (Object member : memberList) {
			if (member != null) {
				bArrList.add(serialize(member));
			}
		}
		return zremMultiByteArrWithSharding(shardingKey, key, bArrList);
	}

	/**
	 * 从有序集合中删除多个指定元素
	 * 
	 * @param key
	 * @param memberList
	 * @return 成功删除的元素个数
	 */

	public Long zremMultiByteArrWithSharding(String shardingKey, String key,
			List<byte[]> memberList) {
		byte[][] memberB = new byte[memberList.size()][];
		for (int i = memberList.size() - 1; i >= 0; i--) {
			memberB[i] = memberList.get(i);
		}

		return zremWithSharding(shardingKey, key, SafeEncoder.encode(key),
				memberB);

	}

	private Long zremWithSharding(String shardingKey, String key,
			byte[] bytekey, byte[]... member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zrem(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/****************************** above:sorted set zremrangeByRank、ZREM、zremMulti *************************/

	/************************** below:sorted set ZCARD、ZCOUNT *********************/
	/**
	 * 获取sorted set 中元素个数
	 * 
	 * @param key
	 * @return
	 */

	public Long zcardWithSharding(String shardingKey, String key) {

		return zcardWithSharding(shardingKey, key, SafeEncoder.encode(key));

	}

	/**
	 * 获取sorted set 中指定范围内的元素个数
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return
	 */

	public Long zcountWithSharding(String shardingKey, String key,
			double minScore, double maxScore) {

		return zcountWithSharding(shardingKey, key, SafeEncoder.encode(key),
				minScore, maxScore);

	}

	private Long zcardWithSharding(String shardingKey, String key,
			byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zcard(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	private Long zcountWithSharding(String shardingKey, String key,
			byte[] bytekey, double minScore, double maxScore) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zcount(bytekey, minScore, maxScore);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/**************************** above:sorted set ZCARD、ZCOUNT *********************/

	/****************************** below:sorted set ZRANK,ZREVRANK、ZSCORE *************************/
	/**
	 * 返回元素在有序集合（从小到大）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrankStringWithSharding(String shardingKey, String key,
			String member) {
		return zrankByteArrWithSharding(shardingKey, key,
				SafeEncoder.encode(member));
	}

	/**
	 * 返回元素在有序集合（从小到大）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrankObjectWithSharding(String shardingKey, String key,
			Object member) {
		return zrankByteArrWithSharding(shardingKey, key, serialize(member));
	}

	/**
	 * 返回元素在有序集合（从小到大）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrankByteArrWithSharding(String shardingKey, String key,
			byte[] member) {
		valueTypeAssert(member);

		return zrankWithSharding(shardingKey, key, SafeEncoder.encode(key),
				member, true);

	}

	/**
	 * 返回元素在有序集合（从大到小）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrevrankStringWithSharding(String shardingKey, String key,
			String member) {
		return zrevrankByteArrWithSharding(shardingKey, key,
				SafeEncoder.encode(member));
	}

	/**
	 * 返回元素在有序集合（从大到小）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrevrankObjectWithSharding(String shardingKey, String key,
			Object member) {
		return zrevrankByteArrWithSharding(shardingKey, key, serialize(member));
	}

	/**
	 * 返回元素在有序集合（从大到小）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrevrankByteArrWithSharding(String shardingKey, String key,
			byte[] member) {
		valueTypeAssert(member);

		return zrankWithSharding(shardingKey, key, SafeEncoder.encode(key),
				member, false);

	}

	private Long zrankWithSharding(String shardingKey, String key,
			byte[] bytekey, byte[] member, boolean isasc) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				if (isasc) {
					Long ret = jedis.zrank(bytekey, member);
					return ret;
				} else {
					Long ret = jedis.zrevrank(bytekey, member);
					return ret;
				}
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * 返回元素在有序集合中的排序因子
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回排序因子score，元素不存在时返回null
	 */

	public Double zscoreStringWithSharding(String shardingKey, String key,
			String member) {
		return zscoreByteArrWithSharding(shardingKey, key,
				SafeEncoder.encode(member));
	}

	/**
	 * 返回元素在有序集合中的排序因子
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回排序因子score，元素不存在时返回null
	 */

	public Double zscoreObjectWithSharding(String shardingKey, String key,
			Object member) {
		return zscoreByteArrWithSharding(shardingKey, key, serialize(member));
	}

	/**
	 * 返回元素在有序集合中的排序因子
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回排序因子score，元素不存在时返回null
	 */

	public Double zscoreByteArrWithSharding(String shardingKey, String key,
			byte[] member) {
		valueTypeAssert(member);

		return zscoreWithSharding(shardingKey, key, SafeEncoder.encode(key),
				member);

	}

	private Double zscoreWithSharding(String shardingKey, String key,
			byte[] bytekey, byte[] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Double ret = jedis.zscore(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/****************************** above:sorted set ZRANK,ZREVRANK、ZSCORE *************************/

	/*************************** below:sorted set ZRANGE、ZREVRANGE *******************/
	/**
	 * 获取指定位置范围内的升序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<String> zrangeStringWithSharding(String shardingKey, String key,
			int start, int end) {
		Set<byte[]> ret = zrangeByteArrWithSharding(shardingKey, key, start,
				end);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>(); // used
																// LinkedHashSet
																// to ensure it
																// is in order
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定位置范围内的升序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<Object> zrangeObjectWithSharding(String shardingKey, String key,
			int start, int end) {
		Set<byte[]> ret = zrangeByteArrWithSharding(shardingKey, key, start,
				end);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定位置范围内的升序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<byte[]> zrangeByteArrWithSharding(String shardingKey,
			String key, int start, int end) {

		return zrangeWithSharding(shardingKey, key, SafeEncoder.encode(key),
				start, end, true);

	}

	/**
	 * 获取指定位置范围内的降序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<String> zrevrangeStringWithSharding(String shardingKey,
			String key, int start, int end) {
		Set<byte[]> ret = zrevrangeByteArrWithSharding(shardingKey, key, start,
				end);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定位置范围内的降序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<Object> zrevrangeObjectWithSharding(String shardingKey,
			String key, int start, int end) {
		Set<byte[]> ret = zrevrangeByteArrWithSharding(shardingKey, key, start,
				end);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定位置范围内的降序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<byte[]> zrevrangeByteArrWithSharding(String shardingKey,
			String key, int start, int end) {

		return zrangeWithSharding(shardingKey, key, SafeEncoder.encode(key),
				start, end, false);

	}

	private Set<byte[]> zrangeWithSharding(String shardingKey, String key,
			byte[] bytekey, int start, int end, boolean isasc) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				if (isasc) {
					Set<byte[]> ret = jedis.zrange(bytekey, start, end);
					return ret;
				} else {
					Set<byte[]> ret = jedis.zrevrange(bytekey, start, end);
					return ret;
				}
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/*************************** above:sorted set ZRANGE、ZREVRANGE *******************/

	/****************************** below:sorted set zrangeByScore、zrevrangeByScore *************************/
	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet 升序结果集
	 */

	public Set<String> zrangeByScoreStringWithSharding(String shardingKey,
			String key, double minScore, double maxScore) {
		Set<byte[]> ret = zrangeByScoreByteArrWithSharding(shardingKey, key,
				minScore, maxScore);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet升序结果集
	 */

	public Set<Object> zrangeByScoreObjectWithSharding(String shardingKey,
			String key, double minScore, double maxScore) {
		Set<byte[]> ret = zrangeByScoreByteArrWithSharding(shardingKey, key,
				minScore, maxScore);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet升序结果集
	 */

	public Set<byte[]> zrangeByScoreByteArrWithSharding(String shardingKey,
			String key, double minScore, double maxScore) {

		return zrangeByScoreWithSharding(shardingKey, key,
				SafeEncoder.encode(key), minScore, maxScore, true);

	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet 降序结果集
	 */

	public Set<String> zrevrangeByScoreStringWithSharding(String shardingKey,
			String key, double maxScore, double minScore) {
		Set<byte[]> ret = zrevrangeByScoreByteArrWithSharding(shardingKey, key,
				maxScore, minScore);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet降序结果集
	 */

	public Set<Object> zrevrangeByScoreObjectWithSharding(String shardingKey,
			String key, double maxScore, double minScore) {
		Set<byte[]> ret = zrevrangeByScoreByteArrWithSharding(shardingKey, key,
				maxScore, minScore);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet降序结果集
	 */

	public Set<byte[]> zrevrangeByScoreByteArrWithSharding(String shardingKey,
			String key, double maxScore, double minScore) {

		return zrangeByScoreWithSharding(shardingKey, key,
				SafeEncoder.encode(key), minScore, maxScore, false);

	}

	private Set<byte[]> zrangeByScoreWithSharding(String shardingKey,
			String key, byte[] bytekey, double minScore, double maxScore,
			boolean isasc) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				if (isasc) {
					Set<byte[]> ret = jedis.zrangeByScore(bytekey, minScore,
							maxScore);
					return ret;
				} else {
					Set<byte[]> ret = jedis.zrevrangeByScore(bytekey, maxScore,
							minScore);
					return ret;
				}
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet 升序结果集
	 */

	public Set<String> zrangeByScoreStringWithSharding(String shardingKey,
			String key, double minScore, double maxScore, int offset, int count) {
		Set<byte[]> ret = zrangeByScoreByteArrWithSharding(shardingKey, key,
				minScore, maxScore, offset, count);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet升序结果集
	 */

	public Set<Object> zrangeByScoreObjectWithSharding(String shardingKey,
			String key, double minScore, double maxScore, int offset, int count) {
		Set<byte[]> ret = zrangeByScoreByteArrWithSharding(shardingKey, key,
				minScore, maxScore, offset, count);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet升序结果集
	 */

	public Set<byte[]> zrangeByScoreByteArrWithSharding(String shardingKey,
			String key, double minScore, double maxScore, int offset, int count) {

		return zrangeByScoreWithSharding(shardingKey, key,
				SafeEncoder.encode(key), minScore, maxScore, offset, count,
				true);

	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet 降序结果集
	 */

	public Set<String> zrevrangeByScoreStringWithSharding(String shardingKey,
			String key, double maxScore, double minScore, int offset, int count) {
		Set<byte[]> ret = zrevrangeByScoreByteArrWithSharding(shardingKey, key,
				maxScore, minScore, offset, count);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet降序结果集
	 */

	public Set<Object> zrevrangeByScoreObjectWithSharding(String shardingKey,
			String key, double maxScore, double minScore, int offset, int count) {
		Set<byte[]> ret = zrevrangeByScoreByteArrWithSharding(shardingKey, key,
				maxScore, minScore, offset, count);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet降序结果集
	 */

	public Set<byte[]> zrevrangeByScoreByteArrWithSharding(String shardingKey,
			String key, double maxScore, double minScore, int offset, int count) {

		return zrangeByScoreWithSharding(shardingKey, key,
				SafeEncoder.encode(key), minScore, maxScore, offset, count,
				false);

	}

	private Set<byte[]> zrangeByScoreWithSharding(String shardingKey,
			String key, byte[] bytekey, double minScore, double maxScore,
			int offset, int count, boolean isasc) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				if (isasc) {
					Set<byte[]> ret = jedis.zrangeByScore(bytekey, minScore,
							maxScore, offset, count);
					return ret;
				} else {
					Set<byte[]> ret = jedis.zrevrangeByScore(bytekey, maxScore,
							minScore, offset, count);
					return ret;
				}
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * 计算给定的一个或多个有序集的交集，并将该交集(结果集)储存到 newkey 。 默认情况下，结果集中某个成员的 score 值是所有给定集下该成员
	 * score 值之和.
	 * 
	 * @param shardingKey
	 *            排序的key，确保所有的集合在一台redis上面
	 * @param newkey
	 *            新创建的key
	 * @param keys
	 *            需要操作的集合的key
	 */
	public void zinterstoreWithSharding(String shardingKey, String newkey,
			String... keys) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(newkey);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				byte[][] bytekes = new byte[keys.length][];
				for (int i = 0; i < keys.length; i++) {
					String key = keys[i];
					bytekes[i] = SafeEncoder.encode(key);
				}
				jedis.zinterstore(SafeEncoder.encode(newkey), bytekes);
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
	}

	/**
	 * 计算给定的一个或多个有序集的并集，其中给定 key 的数量必须以 numkeys 参数指定，并将该并集(结果集)储存到 destination 。
	 * 默认情况下，结果集中某个成员的 score 值是所有给定集下该成员 score 值之 和 。
	 * 
	 * @param shardingKey
	 *            排序的key，确保所有的集合在一台redis上面
	 * @param newkey
	 *            新创建的key
	 * @param keys
	 *            需要操作的集合的key
	 */
	public void zunionstoreWithSharding(String shardingKey, String newkey,
			String... keys) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(newkey);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {

				byte[][] bytekes = new byte[keys.length][];
				for (int i = 0; i < keys.length; i++) {
					String key = keys[i];
					bytekes[i] = SafeEncoder.encode(key);
				}
				jedis.zunionstore(SafeEncoder.encode(newkey), bytekes);
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
	}

	/**
	 * 合集倒序
	 * 
	 * @return
	 */
	public Set<String> zunionstoreRevrangeByScoreString(List<String> keys,
			double maxScore, double minScore, int offset, int count) {
		Set<byte[]> ret = zunionstoreRevrangeByScoreByteArr(keys, maxScore,
				minScore, offset, count);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 合集倒序
	 * 
	 * @return
	 */
	public Set<Object> zunionstoreRevrangeByScoreObject(List<String> keys,
			double maxScore, double minScore, int offset, int count) {
		Set<byte[]> ret = zunionstoreRevrangeByScoreByteArr(keys, maxScore,
				minScore, offset, count);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 合集倒序
	 * 
	 * @return
	 */
	public Set<byte[]> zunionstoreRevrangeByScoreByteArr(List<String> keys,
			double maxScore, double minScore, int offset, int count) {

		return zunionstoreRangeByScore(keys, minScore, maxScore, offset, count,
				false);

	}

	/**
	 * 合集正序
	 * 
	 * @return
	 */
	public Set<String> zunionstoreRangeByScoreString(List<String> keys,
			double minScore, double maxScore, int offset, int count) {
		Set<byte[]> ret = zunionstoreRangeByScoreByteArr(keys, minScore,
				maxScore, offset, count);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 合集正序
	 * 
	 * @return
	 */
	public Set<Object> zunionstoreRangeByScoreObject(List<String> keys,
			double minScore, double maxScore, int offset, int count) {
		Set<byte[]> ret = zunionstoreRangeByScoreByteArr(keys, minScore,
				maxScore, offset, count);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 合集正序
	 * 
	 * @return
	 */
	public Set<byte[]> zunionstoreRangeByScoreByteArr(List<String> keys,
			double minScore, double maxScore, int offset, int count) {

		return zunionstoreRangeByScore(keys, minScore, maxScore, offset, count,
				true);

	}

	private Set<byte[]> zunionstoreRangeByScore(List<String> keys,
			final double minScore, final double maxScore, final int offset,
			final int count, final boolean isasc) {
		long start = System.currentTimeMillis();
		if (keys == null || keys.size() == 0) {
			return null;
		}
		Set<byte[]> ret = new LinkedHashSet<byte[]>();
		final Map<String, List<String>> nodeToKeys = devideKeys(keys);
		final TreeSet<Tuple> treeSets = new TreeSet<Tuple>();

		final CountDownLatch cdl = new CountDownLatch(nodeToKeys.keySet()
				.size());
		for (final String key : nodeToKeys.keySet()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
					try {
						List<String> thisKeys = nodeToKeys.get(key);
						if (thisKeys != null && thisKeys.size() > 0) {

							long start1 = System.currentTimeMillis();
							Set<Tuple> tuples = zunionstoreTuple(thisKeys,
									minScore, maxScore, offset, count, isasc);
							
							long start2 = System.currentTimeMillis();
							if (tuples != null) {
								synchronized (treeSets) {
									treeSets.addAll(tuples);
								}
							}
					
						}
					} finally {
						cdl.countDown();
					}
				}
			});
		}
		try {
			cdl.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
		long start3 = System.currentTimeMillis();
		int size = treeSets.size();
		if (treeSets.size() > 0) {
			if (isasc) {
				for (int i = 0; i < size && i <= count; i++) {
					ret.add(treeSets.pollFirst().getBinaryElement());
				}
			} else {
				for (int i = 0; i < size && i <= count; i++) {
					ret.add(treeSets.pollLast().getBinaryElement());
				}
			}
		}
		
		return ret;
	}

	private Set<Tuple> zunionstoreTuple(List<String> keys, double minScore,
			double maxScore, int offset, int count, boolean isasc) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(keys.iterator().next());
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(keys.iterator().next());
			//jedis.select(dbIndex);
			if (jedis != null) {
				byte[][] bytekes = new byte[keys.size()][];
				for (int i = 0; i < keys.size(); i++) {
					String key = keys.get(i);
					bytekes[i] = SafeEncoder.encode(key);
				}
				String newKey = UUID.randomUUID().toString();
				byte[] bytekey = SafeEncoder.encode(newKey);
				long start2 = System.currentTimeMillis();
				jedis.zunionstore(bytekey, bytekes);
				
				if (isasc) {
					Set<Tuple> ret = jedis.zrangeByScoreWithScores(bytekey,
							minScore, maxScore, offset, count);
					jedis.del(bytekey);
					return ret;
				} else {
					Set<Tuple> ret = jedis.zrevrangeByScoreWithScores(bytekey,
							maxScore, minScore, offset, count);
					jedis.del(bytekey);
					return ret;
				}
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/****************************** above:sorted set zrangeByScore、zrevrangeByScore *************************/

	/****************************** below:sorted set *************************/
	/****************************** above:sorted set *************************/

	/****************************** below:sorted set *************************/
	/****************************** above:sorted set *************************/

	/****************************** below:sorted set *************************/
	/****************************** above:sorted set *************************/

	/**
	 * 对对象进行序列化
	 * 
	 * @param o
	 *            必须实现Serializable接口
	 * @return
	 */

	public byte[] serialize(Object o) {
		// return HessianSerializeUtil.encode(o);
		return JedisXSerializeUtil.encode(o);
	}

	public byte[][] serialize(Object... os) {
		byte[][] result = new byte[os.length][];
		for (int i = 0; i < os.length; i++) {
			result[i] = JedisXSerializeUtil.encode(os[i]);
		}
		return result;
	}

	/**
	 * 与serialize(Object o)接口配合使用，进行反序列化
	 * 
	 * @param bytes
	 * @return
	 */

	public Object deserialize(byte[] bytes) {
		// return HessianSerializeUtil.decode(bytes);
		return JedisXSerializeUtil.decode(bytes);
	}

	private byte[][] getBArrArr(List<String> thisKeys) {
		byte[][] bkeys = new byte[thisKeys.size()][];
		for (int i = thisKeys.size() - 1; i >= 0; i--) {
			bkeys[i] = SafeEncoder.encode(thisKeys.get(i));
		}
		return bkeys;
	}

	private byte[][] getKeyValueBArrArr(List<String> thisKeys,
			Map<String, byte[]> keyValueMap) {
		byte[][] bKeyValues = new byte[thisKeys.size() * 2][];
		for (int i = 0; i < thisKeys.size(); i++) {
			String key = thisKeys.get(i);
			bKeyValues[i + i] = SafeEncoder.encode(key);
			bKeyValues[i + i + 1] = keyValueMap.get(key);
		}
		return bKeyValues;
	}

	private void valueTypeAssert(Object value) {
		if (value == null) {
			throw new JedisXValueNotSupportException(
					"nut support the Object-type of Null");
		}

	}

	/******************************** above:attr ********************************************/

	/****************************** below:sorted set ZADD、zaddMulti *************************/
	/**
	 * Add the specified member having the specifeid score to the sorted set
	 * stored at key. If member is already a member of the sorted set the score
	 * is updated, and the element reinserted in the right position to ensure
	 * sorting. If key does not exist a new sorted set with the specified member
	 * as sole member is created. If the key exists but does not hold a sorted
	 * set value an error is returned.
	 * <p>
	 * The score value can be the string representation of a double precision
	 * floating point number.
	 * <p>
	 * Time complexity O(log(N)) with N being the number of elements in the
	 * sorted set
	 * 
	 * @param key
	 * @param score
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added; 0 if
	 *         the element was already a member of the sorted set and the score
	 *         was updated ; -1 the error happened in server
	 */

	public Long zaddString(String key, double score, String member) {
		return zaddByteArr(key, score, SafeEncoder.encode(member));
	}

	public Long zaddObject(String key, double score, Object member) {
		return zaddByteArr(key, score, serialize(member));
	}

	public Long zaddByteArr(String key, double score, byte[] member) {
		valueTypeAssert(member);

		return zadd(key, SafeEncoder.encode(key), score, member);

	}

	private Long zadd(String key, byte[] bytekey, double score, byte[] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zadd(bytekey, score, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}
	
	public Double zincr(String key, double score, String member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			if (jedis != null) {
				Double ret = jedis.zincrby(key, score, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0.0;
	}

	/**
	 * 往sorted set中插入多个元素
	 * 
	 * @param key
	 * @param scoreMembers
	 * @return 成功插入元素的个数
	 */

	public Long zaddMultiString(String key, Map<Double, String> scoreMembers) {
		Map<Double, byte[]> scoreBMembers = new HashMap<Double, byte[]>();
		for (Map.Entry<Double, String> item : scoreMembers.entrySet()) {
			if (item.getValue() != null) {
				scoreBMembers.put(item.getKey(),
						SafeEncoder.encode(item.getValue()));
			}
		}
		return zaddMultiByteArr(key, scoreBMembers);
	}

	/**
	 * 往sorted set中插入多个元素
	 * 
	 * @param key
	 * @param scoreMembers
	 * @return 成功插入元素的个数
	 */

	public Long zaddMultiObject(String key, Map<Double, Object> scoreMembers) {
		Map<Double, byte[]> scoreBMembers = new HashMap<Double, byte[]>();
		for (Map.Entry<Double, Object> item : scoreMembers.entrySet()) {
			if (item.getValue() != null) {
				scoreBMembers.put(item.getKey(), serialize(item.getValue()));
			}
		}
		return zaddMultiByteArr(key, scoreBMembers);
	}

	/**
	 * 往sorted set中插入多个元素
	 * 
	 * @param key
	 * @param scoreMembers
	 * @return 成功插入元素的个数
	 */

	public Long zaddMultiByteArr(String key, Map<Double, byte[]> scoreMembers) {
		if (scoreMembers == null || scoreMembers.size() == 0) {
			return 0L;
		}

		return zadd(key, SafeEncoder.encode(key), scoreMembers);

	}

	private Long zadd(String key, byte[] bytekey,
			Map<Double, byte[]> scoreMembers) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zadd(bytekey, scoreMembers);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/****************************** above:sorted set ZADD、zaddMulti *************************/

	/****************************** above:sorted set zremrangeByRank、 ZREM、zremMulti *************************/
	/**
	 * 从有序集合中删除指定位置范围元素
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return 所删除的元素个数
	 */

	public Long zremrangeByRank(String key, int start, int end) {

		return zremrangeByRank(key, SafeEncoder.encode(key), start, end);

	}

	private Long zremrangeByRank(String key, byte[] bytekey, int start, int end) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zremrangeByRank(bytekey, start, end);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/**
	 * 从有序集合中删除指定元素
	 * 
	 * @param key
	 * @param member
	 * @return 0，未找到该元素删除不成功； 1，找到并删除成功
	 */

	public Long zremString(String key, String member) {
		return zremByteArr(key, SafeEncoder.encode(member));
	}

	/**
	 * 从有序集合中删除指定元素
	 * 
	 * @param key
	 * @param member
	 * @return 0，未找到该元素删除不成功； 1，找到并删除成功
	 */

	public Long zremObject(String key, Object member) {
		return zremByteArr(key, serialize(member));
	}

	/**
	 * 从有序集合中删除指定元素
	 * 
	 * @param key
	 * @param member
	 * @return 0，未找到该元素删除不成功； 1，找到并删除成功
	 */

	public Long zremByteArr(String key, byte[] member) {
		if (member == null) {
			return 0L;
		}

		return zrem(key, SafeEncoder.encode(key), member);

	}

	/**
	 * 从有序集合中删除多个指定元素
	 * 
	 * @param key
	 * @param memberList
	 * @return 成功删除的元素个数
	 */

	public Long zremMultiString(String key, List<String> memberList) {
		List<byte[]> bArrList = new ArrayList<byte[]>();
		for (String member : memberList) {
			if (member != null) {
				bArrList.add(SafeEncoder.encode(member));
			}
		}
		return zremMultiByteArr(key, bArrList);
	}

	/**
	 * 从有序集合中删除多个指定元素
	 * 
	 * @param key
	 * @param memberList
	 * @return 成功删除的元素个数
	 */

	public Long zremMultiObject(String key, List<Object> memberList) {
		List<byte[]> bArrList = new ArrayList<byte[]>();
		for (Object member : memberList) {
			if (member != null) {
				bArrList.add(serialize(member));
			}
		}
		return zremMultiByteArr(key, bArrList);
	}

	/**
	 * 从有序集合中删除多个指定元素
	 * 
	 * @param key
	 * @param memberList
	 * @return 成功删除的元素个数
	 */

	public Long zremMultiByteArr(String key, List<byte[]> memberList) {
		byte[][] memberB = new byte[memberList.size()][];
		for (int i = memberList.size() - 1; i >= 0; i--) {
			memberB[i] = memberList.get(i);
		}

		return zrem(key, SafeEncoder.encode(key), memberB);

	}

	private Long zrem(String key, byte[] bytekey, byte[]... member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zrem(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/****************************** above:sorted set zremrangeByRank、ZREM、zremMulti *************************/

	/************************** below:sorted set ZCARD、ZCOUNT *********************/
	/**
	 * 获取sorted set 中元素个数
	 * 
	 * @param key
	 * @return
	 */

	public Long zcard(String key) {

		return zcard(key, SafeEncoder.encode(key));

	}

	/**
	 * 获取sorted set 中指定范围内的元素个数
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return
	 */

	public Long zcount(String key, double minScore, double maxScore) {

		return zcount(key, SafeEncoder.encode(key), minScore, maxScore);

	}

	private Long zcard(String key, byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zcard(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	private Long zcount(String key, byte[] bytekey, double minScore,
			double maxScore) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.zcount(bytekey, minScore, maxScore);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/**************************** above:sorted set ZCARD、ZCOUNT *********************/

	/****************************** below:sorted set ZRANK,ZREVRANK、ZSCORE *************************/
	/**
	 * 返回元素在有序集合（从小到大）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrankString(String key, String member) {
		return zrankByteArr(key, SafeEncoder.encode(member));
	}

	/**
	 * 返回元素在有序集合（从小到大）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrankObject(String key, Object member) {
		return zrankByteArr(key, serialize(member));
	}

	/**
	 * 返回元素在有序集合（从小到大）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrankByteArr(String key, byte[] member) {
		valueTypeAssert(member);

		return zrank(key, SafeEncoder.encode(key), member, true);

	}

	/**
	 * 返回元素在有序集合（从大到小）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrevrankString(String key, String member) {
		return zrevrankByteArr(key, SafeEncoder.encode(member));
	}

	/**
	 * 返回元素在有序集合（从大到小）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrevrankObject(String key, Object member) {
		return zrevrankByteArr(key, serialize(member));
	}

	/**
	 * 返回元素在有序集合（从大到小）中的序号（从0开始）
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回序号，元素不存在时返回null
	 */

	public Long zrevrankByteArr(String key, byte[] member) {
		valueTypeAssert(member);

		return zrank(key, SafeEncoder.encode(key), member, false);

	}

	private Long zrank(String key, byte[] bytekey, byte[] member, boolean isasc) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				if (isasc) {
					Long ret = jedis.zrank(bytekey, member);
					return ret;
				} else {
					Long ret = jedis.zrevrank(bytekey, member);
					return ret;
				}
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * 返回元素在有序集合中的排序因子
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回排序因子score，元素不存在时返回null
	 */

	public Double zscoreString(String key, String member) {
		return zscoreByteArr(key, SafeEncoder.encode(member));
	}

	/**
	 * 返回元素在有序集合中的排序因子
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回排序因子score，元素不存在时返回null
	 */

	public Double zscoreObject(String key, Object member) {
		return zscoreByteArr(key, serialize(member));
	}

	/**
	 * 返回元素在有序集合中的排序因子
	 * 
	 * @param key
	 * @param member
	 * @return 如果元素存在时返回排序因子score，元素不存在时返回null
	 */

	public Double zscoreByteArr(String key, byte[] member) {
		valueTypeAssert(member);

		return zscore(key, SafeEncoder.encode(key), member);

	}

	private Double zscore(String key, byte[] bytekey, byte[] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Double ret = jedis.zscore(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/****************************** above:sorted set ZRANK,ZREVRANK、ZSCORE *************************/

	/*************************** below:sorted set ZRANGE、ZREVRANGE *******************/
	/**
	 * 获取指定位置范围内的升序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<String> zrangeString(String key, int start, int end) {
		Set<byte[]> ret = zrangeByteArr(key, start, end);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>(); // used
																// LinkedHashSet
																// to ensure it
																// is in order
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定位置范围内的升序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<Object> zrangeObject(String key, int start, int end) {
		Set<byte[]> ret = zrangeByteArr(key, start, end);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定位置范围内的升序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<byte[]> zrangeByteArr(String key, int start, int end) {

		return zrange(key, SafeEncoder.encode(key), start, end, true);

	}

	/**
	 * 获取指定位置范围内的降序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<String> zrevrangeString(String key, int start, int end) {
		Set<byte[]> ret = zrevrangeByteArr(key, start, end);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}
	
	public Set<Tuple> zrevrangeWithScores(String key, long start, long end) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			if (jedis != null) {
				return jedis.zrevrangeWithScores(key, start, end);
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}
	
	public Set<Tuple> zrevrangeByScoreWithScores(String key, long min, long max, int count) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			if (jedis != null) {
				return jedis.zrevrangeByScoreWithScores(key, max, min, 0, count);
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}
	
	public Set<Tuple> zrangeByScoreWithScores(String key, long min, long max, int count) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			if (jedis != null) {
				return jedis.zrangeByScoreWithScores(key, min, max, 0, count);
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}
	
	public Long zremrangeByScore(String key, long start, long end) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			if (jedis != null) {
				return jedis.zremrangeByScore(key, start, end);
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0l;
	}

	/**
	 * 获取指定位置范围内的降序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<Object> zrevrangeObject(String key, int start, int end) {
		Set<byte[]> ret = zrevrangeByteArr(key, start, end);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定位置范围内的降序集合
	 * 
	 * @param key
	 * @param start
	 * @param end
	 * @return LinkedHashSet结果集
	 */

	public Set<byte[]> zrevrangeByteArr(String key, int start, int end) {

		return zrange(key, SafeEncoder.encode(key), start, end, false);

	}

	private Set<byte[]> zrange(String key, byte[] bytekey, int start, int end,
			boolean isasc) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				if (isasc) {
					Set<byte[]> ret = jedis.zrange(bytekey, start, end);
					return ret;
				} else {
					Set<byte[]> ret = jedis.zrevrange(bytekey, start, end);
					return ret;
				}
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/*************************** above:sorted set ZRANGE、ZREVRANGE *******************/

	/****************************** below:sorted set zrangeByScore、zrevrangeByScore *************************/
	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet 升序结果集
	 */

	public Set<String> zrangeByScoreString(String key, double minScore,
			double maxScore) {
		Set<byte[]> ret = zrangeByScoreByteArr(key, minScore, maxScore);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet升序结果集
	 */

	public Set<Object> zrangeByScoreObject(String key, double minScore,
			double maxScore) {
		Set<byte[]> ret = zrangeByScoreByteArr(key, minScore, maxScore);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet升序结果集
	 */

	public Set<byte[]> zrangeByScoreByteArr(String key, double minScore,
			double maxScore) {

		return zrangeByScore(key, SafeEncoder.encode(key), minScore, maxScore,
				true);

	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet 降序结果集
	 */

	public Set<String> zrevrangeByScoreString(String key, double maxScore,
			double minScore) {
		Set<byte[]> ret = zrevrangeByScoreByteArr(key, maxScore, minScore);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet降序结果集
	 */

	public Set<Object> zrevrangeByScoreObject(String key, double maxScore,
			double minScore) {
		Set<byte[]> ret = zrevrangeByScoreByteArr(key, maxScore, minScore);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @return LinkedHashSet降序结果集
	 */

	public Set<byte[]> zrevrangeByScoreByteArr(String key, double maxScore,
			double minScore) {

		return zrangeByScore(key, SafeEncoder.encode(key), minScore, maxScore,
				false);

	}

	private Set<byte[]> zrangeByScore(String key, byte[] bytekey,
			double minScore, double maxScore, boolean isasc) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				if (isasc) {
					Set<byte[]> ret = jedis.zrangeByScore(bytekey, minScore,
							maxScore);
					return ret;
				} else {
					Set<byte[]> ret = jedis.zrevrangeByScore(bytekey, maxScore,
							minScore);
					return ret;
				}
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet 升序结果集
	 */

	public Set<String> zrangeByScoreString(String key, double minScore,
			double maxScore, int offset, int count) {
		Set<byte[]> ret = zrangeByScoreByteArr(key, minScore, maxScore, offset,
				count);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet升序结果集
	 */

	public Set<Object> zrangeByScoreObject(String key, double minScore,
			double maxScore, int offset, int count) {
		Set<byte[]> ret = zrangeByScoreByteArr(key, minScore, maxScore, offset,
				count);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet升序结果集
	 */

	public Set<byte[]> zrangeByScoreByteArr(String key, double minScore,
			double maxScore, int offset, int count) {

		return zrangeByScore(key, SafeEncoder.encode(key), minScore, maxScore,
				offset, count, true);

	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet 降序结果集
	 */

	public Set<String> zrevrangeByScoreString(String key, double maxScore,
			double minScore, int offset, int count) {
		Set<byte[]> ret = zrevrangeByScoreByteArr(key, maxScore, minScore,
				offset, count);
		if (ret != null) {
			Set<String> trueRet = new LinkedHashSet<String>();
			for (byte[] item : ret) {
				trueRet.add(SafeEncoder.encode(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet降序结果集
	 */

	public Set<Object> zrevrangeByScoreObject(String key, double maxScore,
			double minScore, int offset, int count) {
		Set<byte[]> ret = zrevrangeByScoreByteArr(key, maxScore, minScore,
				offset, count);
		if (ret != null) {
			Set<Object> trueRet = new LinkedHashSet<Object>();
			for (byte[] item : ret) {
				trueRet.add(deserialize(item));
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * 获取指定排序因子score范围内的元素
	 * 
	 * @param key
	 * @param minScore
	 * @param maxScore
	 * @param offset
	 * @param count
	 * @return LinkedHashSet降序结果集
	 */

	public Set<byte[]> zrevrangeByScoreByteArr(String key, double maxScore,
			double minScore, int offset, int count) {

		return zrangeByScore(key, SafeEncoder.encode(key), minScore, maxScore,
				offset, count, false);

	}

	private Set<byte[]> zrangeByScore(String key, byte[] bytekey,
			double minScore, double maxScore, int offset, int count,
			boolean isasc) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				if (isasc) {
					Set<byte[]> ret = jedis.zrangeByScore(bytekey, minScore,
							maxScore, offset, count);
					return ret;
				} else {
					Set<byte[]> ret = jedis.zrevrangeByScore(bytekey, maxScore,
							minScore, offset, count);
					return ret;
				}
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/****************************** above:sorted set zrangeByScore、zrevrangeByScore *************************/

	/******************************* below:set sadd,srem,spop,smember **********************/
	/**
	 * 往集合中插入member
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long saddStringWithSharding(String shardingKey, String key,
			String member) {
		return saddByteArrWithSharding(shardingKey, key,
				SafeEncoder.encode(member));
	}

	/**
	 * 往集合中插入member(复杂对象是否适应于此方法有待测试验证)
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long saddObjectWithSharding(String shardingKey, String key,
			Object member) {
		return saddByteArrWithSharding(shardingKey, key, serialize(member));
	}

	/**
	 * 往集合中插入member
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long saddByteArrWithSharding(String shardingKey, String key,
			byte[] member) {
		valueTypeAssert(member);

		return saddWithSharding(shardingKey, key, SafeEncoder.encode(key),
				member);

	}

	private Long saddWithSharding(String shardingKey, String key,
			byte[] bytekey, byte[] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.sadd(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/******************************* below:set sadd,srem,spop,smember **********************/
	/**
	 * 往集合中插入member
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long smultiAddStringWithSharding(String shardingKey, String key,
			String... members) {
		return smultiAddByteArrWithSharding(shardingKey, key,
				SafeEncoder.encodeMany(members));
	}

	/**
	 * 往集合中插入member(复杂对象是否适应于此方法有待测试验证)
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long smultiAddObjectWithSharding(String shardingKey, String key,
			Object... members) {
		return smultiAddByteArrWithSharding(shardingKey, key,
				serialize(members));
	}

	/**
	 * 往集合中插入member
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was added 0 if
	 *         the element was already a member of the set
	 */

	public Long smultiAddByteArrWithSharding(String shardingKey, String key,
			byte[][] members) {
		valueTypeAssert(members);

		return smultiAddWithSharding(shardingKey, key, SafeEncoder.encode(key),
				members);

	}

	private Long smultiAddWithSharding(String shardingKey, String key,
			byte[] bytekey, byte[][] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.sadd(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/**
	 * 删除集合中的member成员
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was removed 0
	 *         if the new element was not a member of the set
	 */

	public Long sremStringWithSharding(String shardingKey, String key,
			String member) {
		return sremByteArrWithSharding(shardingKey, key,
				SafeEncoder.encode(member));
	}

	/**
	 * 删除集合中的member成员（复杂对象是否适合此方法有待测试）
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was removed 0
	 *         if the new element was not a member of the set
	 */

	public Long sremObjectWithSharding(String shardingKey, String key,
			Object member) {
		return sremByteArrWithSharding(shardingKey, key, serialize(member));
	}

	/**
	 * 删除集合中的member成员
	 * 
	 * @param key
	 * @param member
	 * @return Integer reply, specifically: 1 if the new element was removed 0
	 *         if the new element was not a member of the set
	 */

	public Long sremByteArrWithSharding(String shardingKey, String key,
			byte[] member) {
		valueTypeAssert(member);

		return sremWithSharding(shardingKey, key, SafeEncoder.encode(key),
				member);

	}

	public Long smultiRemByteArrWithSharding(String shardingKey, String key,
			byte[][] members) {
		valueTypeAssert(members);
		return smultiRemWithSharding(shardingKey, key, SafeEncoder.encode(key),
				members);
	}

	public Long smultiRemObjectWithSharding(String shardingKey, String key,
			Object... members) {
		return smultiRemByteArrWithSharding(shardingKey, key,
				serialize(members));
	}

	public Long smultiRemStringWithSharding(String shardingKey, String key,
			String... members) {
		return smultiRemByteArrWithSharding(shardingKey, key,
				SafeEncoder.encodeMany(members));
	}

	private Long smultiRemWithSharding(String shardingKey, String key,
			byte[] bytekey, byte[][] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.srem(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	private Long sremWithSharding(String shardingKey, String key,
			byte[] bytekey, byte[] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.srem(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/**
	 * Remove and return a random member from a set
	 * 
	 * @param key
	 * @return
	 */

	public String spopStringWithSharding(String shardingKey, String key) {
		byte[] ret = spopByteArrWithSharding(shardingKey, key);
		if (ret != null) {
			return SafeEncoder.encode(ret);
		}
		return null;
	}

	/**
	 * Remove and return a random member from a set
	 * 
	 * @param key
	 * @return
	 */

	public Object spopObjectWithSharding(String shardingKey, String key) {
		byte[] ret = spopByteArrWithSharding(shardingKey, key);
		if (ret != null) {
			return deserialize(ret);
		}
		return null;
	}

	/**
	 * Remove and return a random member from a set
	 * 
	 * @param key
	 * @return
	 */

	public byte[] spopByteArrWithSharding(String shardingKey, String key) {

		return spopWithSharding(shardingKey, key, SafeEncoder.encode(key));

	}

	private byte[] spopWithSharding(String shardingKey, String key,
			byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				byte[] ret = jedis.spop(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/**
	 * Get all the members in a set
	 * 
	 * @param key
	 * @return
	 */

	public Set<String> smemberStringWithSharding(String shardingKey, String key) {
		Set<byte[]> ret = smemberByteArrWithSharding(shardingKey, key);
		if (ret != null) {
			Set<String> trueRet = new HashSet<String>();
			for (byte[] member : ret) {
				if (member != null) {
					trueRet.add(SafeEncoder.encode(member));
				}
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * Get all the members in a set
	 * 
	 * @param key
	 * @return
	 */

	public Set<Object> smemberObjectWithSharding(String shardingKey, String key) {
		Set<byte[]> ret = smemberByteArrWithSharding(shardingKey, key);
		if (ret != null) {
			Set<Object> trueRet = new HashSet<Object>();
			for (byte[] member : ret) {
				if (member != null) {
					trueRet.add(deserialize(member));
				}
			}
			return trueRet;
		}
		return null;
	}

	/**
	 * Get all the members in a set
	 * 
	 * @param key
	 * @return
	 */

	public Set<byte[]> smemberByteArrWithSharding(String shardingKey, String key) {

		return smemberWithSharding(shardingKey, key, SafeEncoder.encode(key));

	}

	private Set<byte[]> smemberWithSharding(String shardingKey, String key,
			byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Set<byte[]> ret = jedis.smembers(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return null;
	}

	/******************************** above:set sadd,srem,spop,smember *************************/

	/******************************* below:set scard,sismember *******************************/
	/**
	 * 判断某个member是否在此集合中
	 * 
	 * @param key
	 * @param member
	 * @return
	 */

	public Boolean sismemberStringWithSharding(String shardingKey, String key,
			String member) {
		return sismemberByteArrWithSharding(shardingKey, key,
				SafeEncoder.encode(member));
	}

	/**
	 * 判断某个member是否在此集合中
	 * 
	 * @param key
	 * @param member
	 * @return
	 */

	public Boolean sismemberObjectWithSharding(String shardingKey, String key,
			Object member) {
		return sismemberByteArrWithSharding(shardingKey, key, serialize(member));
	}

	/**
	 * 判断某个member是否在此集合中
	 * 
	 * @param key
	 * @param member
	 * @return
	 */

	public Boolean sismemberByteArrWithSharding(String shardingKey, String key,
			byte[] member) {
		if (member == null) {
			return false;
		}

		return sismemberWithSharding(shardingKey, key, SafeEncoder.encode(key),
				member);

	}

	private Boolean sismemberWithSharding(String shardingKey, String key,
			byte[] bytekey, byte[] member) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Boolean ret = jedis.sismember(bytekey, member);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return false;
	}

	/**
	 * Get the number of members in a set
	 * 
	 * @param key
	 * @return
	 */

	public Long scardWithSharding(String shardingKey, String key) {

		return scardWithSharding(shardingKey, key, SafeEncoder.encode(key));

	}

	private Long scardWithSharding(String shardingKey, String key,
			byte[] bytekey) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Long ret = jedis.scard(bytekey);
				return ret;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return 0L;
	}

	/**
	 * 计算给定的一个或多个有序集的交集，并将该交集(结果集)储存到 newkey 。 默认情况下，结果集中某个成员的 score 值是所有给定集下该成员
	 * score 值之和.
	 * 
	 * @param shardingKey
	 *            排序的key，确保所有的集合在一台redis上面
	 * @param newkey
	 *            新创建的key
	 * @param keys
	 *            需要操作的集合的key
	 */
	public void sinterstoreWithSharding(String shardingKey, String newkey,
			String... keys) {
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(newkey);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(shardingKey);
			//jedis.select(dbIndex);
			if (jedis != null) {
				byte[][] bytekes = new byte[keys.length][];
				for (int i = 0; i < keys.length; i++) {
					String key = keys[i];
					bytekes[i] = SafeEncoder.encode(key);
				}
				jedis.sinterstore(SafeEncoder.encode(newkey), bytekes);
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}

	}

	/******************************** above:set scard,sismember *******************************/

	/****************************** below: set sinter，sinterstore *************************/

	/****************************** above: set sinter，sinterstore *************************/

	
	
	
	//=================

	public Map<String, Boolean> pipExists(List<String> keys) {
		final Map<String, Boolean> ret = new ConcurrentHashMap<String, Boolean>();
		final Map<String, List<String>> nodeToKeys = devideKeys(keys);
		final CountDownLatch cdl = new CountDownLatch(nodeToKeys.keySet()
				.size());

		for (final String key : nodeToKeys.keySet()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
					try {
						List<String> thisKeys = nodeToKeys.get(key);
						if (thisKeys != null && thisKeys.size() > 0) {
							Map<String, Boolean> thisret = pipExists(key,
									getBArrArr(thisKeys));
							if (thisret != null) {
								ret.putAll(thisret);
							}
						}
					} finally {
						cdl.countDown();
					}
				}
			});

		}
		try {
			cdl.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return ret;
	}
	

	private Map<String,Boolean> pipExists(String key, byte[]... keys) {
		Map<String, Boolean> map = new HashMap<String, Boolean>();
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Pipeline pipeline = jedis.pipelined();
				for( byte[] subKey:keys){
					pipeline.exists(subKey);
				}
				List<Object> ret = pipeline.syncAndReturnAll();
				for (int i = ret.size() - 1; i >= 0; i--) {
					if(ret.get(i)!=null)
					map.put(SafeEncoder.encode(keys[i]), (Boolean)ret.get(i));
				}
				return map;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return map;
	}
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	
	private Map<String, List<RedisKeyMemByte>> devideKeysRequest(List<RedisKeyMemByte> requests) {
		Map<JedisShardInfo, List<RedisKeyMemByte>> map = new HashMap<JedisShardInfo, List<RedisKeyMemByte>>();
		Map<String, List<RedisKeyMemByte>> result = new HashMap<String, List<RedisKeyMemByte>>();
		ShardedJedis shardJedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			for (RedisKeyMemByte redisKeyMemByte : requests) {
				JedisShardInfo jedisShardInfo = shardJedis.getShardInfo(redisKeyMemByte.getKey());
				List<RedisKeyMemByte> keysList = map.get(jedisShardInfo);

				if (keysList == null) {
					keysList = new ArrayList<RedisKeyMemByte>();
					map.put(jedisShardInfo, keysList);
				}
				keysList.add(redisKeyMemByte);
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage(), e);
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		for (List<RedisKeyMemByte> list : map.values()) {
			result.put(list.iterator().next().getKey(), list);
		}
		return result;
	}

	
	
	
	private Map<String, List<RedisKeySortMemByte>> devideSortKeysRequest(List<RedisKeySortMemByte> requests) {
		Map<JedisShardInfo, List<RedisKeySortMemByte>> map = new HashMap<JedisShardInfo, List<RedisKeySortMemByte>>();
		Map<String, List<RedisKeySortMemByte>> result = new HashMap<String, List<RedisKeySortMemByte>>();
		ShardedJedis shardJedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			for (RedisKeySortMemByte redisKeySortMemByte : requests) {
				JedisShardInfo jedisShardInfo = shardJedis.getShardInfo(redisKeySortMemByte.getKey());
				List<RedisKeySortMemByte> keysList = map.get(jedisShardInfo);

				if (keysList == null) {
					keysList = new ArrayList<RedisKeySortMemByte>();
					map.put(jedisShardInfo, keysList);
				}
				keysList.add(redisKeySortMemByte);
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage(), e);
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		for (List<RedisKeySortMemByte> list : map.values()) {
			result.put(list.iterator().next().getKey(), list);
		}
		return result;
	}
	
	

	private Map<String, List<RedisKeyHashMemByte>> devideHashKeysRequest(List<RedisKeyHashMemByte> requests) {
		Map<JedisShardInfo, List<RedisKeyHashMemByte>> map = new HashMap<JedisShardInfo, List<RedisKeyHashMemByte>>();
		Map<String, List<RedisKeyHashMemByte>> result = new HashMap<String, List<RedisKeyHashMemByte>>();
		ShardedJedis shardJedis = null;
		try {
			shardJedis = shardedJedisPool.getResource();
			for (RedisKeyHashMemByte redisKeySortMemByte : requests) {
				JedisShardInfo jedisShardInfo = shardJedis.getShardInfo(redisKeySortMemByte.getKey());
				List<RedisKeyHashMemByte> keysList = map.get(jedisShardInfo);

				if (keysList == null) {
					keysList = new ArrayList<RedisKeyHashMemByte>();
					map.put(jedisShardInfo, keysList);
				}
				keysList.add(redisKeySortMemByte);
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage(), e);
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		for (List<RedisKeyHashMemByte> list : map.values()) {
			result.put(list.iterator().next().getKey(), list);
		}
		return result;
	}
	
	//============pipZscoreByteArr=====
	
	public Map<RedisKeyMemObj, Double> pipZscoreObject(List<RedisKeyMemObj> requests) {
		 Map<RedisKeyMemByte, Double> result= pipZscoreByteArr(RedisData.getRedisKeyMemByteListFromObj(requests));
		 Map<RedisKeyMemObj, Double> ret=new HashMap<RedisKeyMemObj, Double>();
		 for(RedisKeyMemByte key:result.keySet()){
			 ret.put(RedisData.getRedisKeyMemObj(key), result.get(key));
		 }
		 return ret;
	}
	
	public Map<RedisKeyMemStr, Double> pipZscoreString(List<RedisKeyMemStr> requests) {
		 Map<RedisKeyMemByte, Double> result= pipZscoreByteArr(RedisData.getRedisKeyMemByteList(requests));
		 Map<RedisKeyMemStr, Double> ret=new HashMap<RedisKeyMemStr, Double>();
		 for(RedisKeyMemByte key:result.keySet()){
			 ret.put(RedisData.getRedisKeyMemStr(key), result.get(key));
		 }
		 return ret;
	}
	
	

	public Map<RedisKeyMemByte, Double> pipZscoreByteArr(List<RedisKeyMemByte> requests) {
		final Map<RedisKeyMemByte, Double> ret = new ConcurrentHashMap<RedisKeyMemByte, Double>();
		final Map<String,List< RedisKeyMemByte>> nodeToKeys = devideKeysRequest(requests);
		final CountDownLatch cdl = new CountDownLatch(nodeToKeys.keySet()
				.size());

		for (final String key : nodeToKeys.keySet()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
					try {
						List< RedisKeyMemByte>  subRequest= nodeToKeys.get(key);
						if (subRequest != null && subRequest.size() > 0) {
							Map<RedisKeyMemByte, Double> thisret = pipZscoreByteArr(key,RedisData.getRedisKeyByteMemByteList(subRequest));
							if (thisret != null) {
								ret.putAll(thisret);
							}
						}
					} finally {
						cdl.countDown();
					}
				}
			});
		}
		try {
			cdl.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}

		return ret;
	}
	

	private Map<RedisKeyMemByte,Double> pipZscoreByteArr(String key, List<RedisKeyByteMemByte>  requests) {
		Map<RedisKeyMemByte, Double> map = new HashMap<RedisKeyMemByte, Double>();
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Pipeline pipeline = jedis.pipelined();
				for(int i=0;i<requests.size();i++){
					pipeline.zscore(requests.get(i).getKey(), requests.get(i).getMem());
				}
				List<Object> ret = pipeline.syncAndReturnAll();
				for (int i = ret.size() - 1; i >= 0; i--) {
					if(ret.get(i)!=null)
					map.put(RedisData.getRedisKeyMemByte(requests.get(i)), (Double)ret.get(i));
				}
				return map;
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
		return map;
	}
	
	
	

	
	
	

	//=====hDelete

	public void pipHDeleteObject(List<RedisKeyMemObj> requests) {
		pipHDeleteByte(RedisData.getRedisKeyMemByteListFromObj(requests)); 
	}
	
	public void pipHDeleteObjectAsyn(List<RedisKeyMemObj> requests) {
		pipHDeleteByteAsyn(RedisData.getRedisKeyMemByteListFromObj(requests)); 
	}
	
	public void pipHDeleteStr(List<RedisKeyMemStr> requests) {
		pipHDeleteByte(RedisData.getRedisKeyMemByteList(requests));
	}
	
	public void pipHDeleteStrAsyn(List<RedisKeyMemStr> requests) {
		pipHDeleteByteAsyn(RedisData.getRedisKeyMemByteList(requests));
	}
	
	
	public void pipHDeleteByteAsyn(List<RedisKeyMemByte> requests) {
		final Map<String,List< RedisKeyMemByte>> nodeToKeys = devideKeysRequest(requests);
		for (final String key : nodeToKeys.keySet()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
						List< RedisKeyMemByte>  subRequest= nodeToKeys.get(key);
						if (subRequest != null && subRequest.size() > 0) {
							 pipHDelete(key,RedisData.getRedisKeyByteMemByteList(subRequest));
						}
				}
			});
		}
		
	}
	

	public void pipHDeleteByte(List<RedisKeyMemByte> requests) {
		final Map<String,List< RedisKeyMemByte>> nodeToKeys = devideKeysRequest(requests);
		final CountDownLatch cdl = new CountDownLatch(nodeToKeys.keySet()
				.size());

		for (final String key : nodeToKeys.keySet()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
					try {
						List< RedisKeyMemByte>  subRequest= nodeToKeys.get(key);
						if (subRequest != null && subRequest.size() > 0) {
							 pipHDelete(key,RedisData.getRedisKeyByteMemByteList(subRequest));
						}
					} finally {
						cdl.countDown();
					}
				}
			});
		}
		try {
			cdl.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	

	private void pipHDelete(String key, List<RedisKeyByteMemByte>  requests) {
		
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Pipeline pipeline = jedis.pipelined();
				for(int i=0;i<requests.size();i++){
					pipeline.hdel(requests.get(i).getKey(), requests.get(i).getMem());
				}
				pipeline.syncAndReturnAll();
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
	}
	
	
	
	
	
	//=====hGet

		
		
		public Map<RedisKeyMemByte, byte[]> pipHGetByte(List<RedisKeyMemByte> requests) {
			final Map<RedisKeyMemByte, byte[]> ret = new ConcurrentHashMap<RedisKeyMemByte, byte[]>();
			final Map<String,List< RedisKeyMemByte>> nodeToKeys = devideKeysRequest(requests);
			final CountDownLatch cdl = new CountDownLatch(nodeToKeys.keySet()
					.size());

			for (final String key : nodeToKeys.keySet()) {
				executorService.execute(new Runnable() {
					@Override
					public void run() {
						try {
							List< RedisKeyMemByte>  subRequest= nodeToKeys.get(key);
							if (subRequest != null && subRequest.size() > 0) {
								Map<RedisKeyMemByte, byte[]> thisret = pipHGet(key,RedisData.getRedisKeyByteMemByteList(subRequest));
								if (thisret != null) {
									ret.putAll(thisret);
								}
							}
						} finally {
							cdl.countDown();
						}
					}
				});
			}
			try {
				cdl.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			return ret;
		}
		

		private Map<RedisKeyMemByte, byte[]> pipHGet(String key, List<RedisKeyByteMemByte>  requests) {
			Map<RedisKeyMemByte, byte[]> map = new HashMap<RedisKeyMemByte, byte[]>();
			ShardedJedis shardJedis = null;
			Jedis jedis = null;
			try {
				int dbIndex = this.getDBIndex(key);
				shardJedis = shardedJedisPool.getResource();
				jedis = shardJedis.getShard(key);
				//jedis.select(dbIndex);
				if (jedis != null) {
					
					Pipeline pipeline = jedis.pipelined();
					Class clazz=pipeline.getClass();
					Field field=ReflectUtil.getFieldByName("client", clazz);
					field.setAccessible(true);
					Client client=	(Client) field.get(pipeline);
					Method me=ReflectUtil.getMethodByName("getResponse", Builder.class, clazz);
					me.setAccessible(true);
					for(int i=0;i<requests.size();i++){
						client.hget(requests.get(i).getKey(), requests.get(i).getMem());
						me.invoke(pipeline, BuilderFactory.BYTE_ARRAY);
					}
					List<Object> ret=pipeline.syncAndReturnAll();
					
					for (int i = ret.size() - 1; i >= 0; i--) {
						if(ret.get(i)!=null)
						map.put(RedisData.getRedisKeyMemByte(requests.get(i)), (byte[])ret.get(i));
					}
					return map;
				}
			} catch (Exception e) {
				if (shardJedis != null) {
					shardedJedisPool.returnBrokenResource(shardJedis);
				}
				log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
				jedis = null;
			} finally {
				if (shardJedis != null) {
					shardedJedisPool.returnResource(shardJedis);
				}
			}
			return map;
		}
		
		
		
	
	
	
		//=====hSet

		public void pipHSetObject(List<RedisKeyHashMemObj> requests) {
			pipHSetByte(RedisHashData.getRedisKeyHashMemByteListFromObj(requests)); 
		}
		
		public void pipHSetObjectAsyn(List<RedisKeyHashMemObj> requests) {
			pipHSetByteAsyn(RedisHashData.getRedisKeyHashMemByteListFromObj(requests)); 
		}
		
		public void pipHSetStr(List<RedisKeyHashMemStr> requests) {
			pipHSetByte(RedisHashData.getRedisKeyHashMemByteList(requests));
		}
		
		public void pipHSetStrAsyn(List<RedisKeyHashMemStr> requests) {
			pipHSetByteAsyn(RedisHashData.getRedisKeyHashMemByteList(requests));
		}
		
		
		public void pipHSetByteAsyn(List<RedisKeyHashMemByte> requests) {
			final Map<String,List< RedisKeyHashMemByte>> nodeToKeys = devideHashKeysRequest(requests);
			for (final String key : nodeToKeys.keySet()) {
				executorService.execute(new Runnable() {
					@Override
					public void run() {
							List< RedisKeyHashMemByte>  subRequest= nodeToKeys.get(key);
							if (subRequest != null && subRequest.size() > 0) {
								 pipHSet(key,RedisHashData.getRedisKeyHashByteMemByteList(subRequest));
							}
					}
				});
			}
			
		}
		

		public void pipHSetByte(List<RedisKeyHashMemByte> requests) {
			final Map<String,List< RedisKeyHashMemByte>> nodeToKeys = devideHashKeysRequest(requests);
			final CountDownLatch cdl = new CountDownLatch(nodeToKeys.keySet()
					.size());

			for (final String key : nodeToKeys.keySet()) {
				executorService.execute(new Runnable() {
					@Override
					public void run() {
						try {
							List< RedisKeyHashMemByte>  subRequest= nodeToKeys.get(key);
							if (subRequest != null && subRequest.size() > 0) {
								 pipHSet(key,RedisHashData.getRedisKeyHashByteMemByteList(subRequest));
							}
						} finally {
							cdl.countDown();
						}
					}
				});
			}
			try {
				cdl.await();
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
		}
		

		private void pipHSet(String key, List<RedisKeyHashByteMemByte>  requests) {
			
			ShardedJedis shardJedis = null;
			Jedis jedis = null;
			try {
				int dbIndex = this.getDBIndex(key);
				shardJedis = shardedJedisPool.getResource();
				jedis = shardJedis.getShard(key);
				//jedis.select(dbIndex);
				if (jedis != null) {
					Pipeline pipeline = jedis.pipelined();
					for(int i=0;i<requests.size();i++){
						pipeline.hset(requests.get(i).getKey(), requests.get(i).getMem(),requests.get(i).getResult());
					}
					pipeline.syncAndReturnAll();
				}
			} catch (Exception e) {
				if (shardJedis != null) {
					shardedJedisPool.returnBrokenResource(shardJedis);
				}
				log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
				jedis = null;
			} finally {
				if (shardJedis != null) {
					shardedJedisPool.returnResource(shardJedis);
				}
			}
		}
		
		
	
	
	
	
	//===============ZremByteArr
	
	public void pipZremObject(List<RedisKeyMemObj> requests) {
		pipZremByte(RedisData.getRedisKeyMemByteListFromObj(requests)); 
	}
	
	public void pipZremObjectAsyn(List<RedisKeyMemObj> requests) {
		pipZremByteAsyn(RedisData.getRedisKeyMemByteListFromObj(requests)); 
	}
	
	public void pipZremStr(List<RedisKeyMemStr> requests) {
		pipZremByte(RedisData.getRedisKeyMemByteList(requests));
	}
	
	public void pipZremStrAsyn(List<RedisKeyMemStr> requests) {
		pipZremByteAsyn(RedisData.getRedisKeyMemByteList(requests));
	}
	
	
	public void pipZremByteAsyn(List<RedisKeyMemByte> requests) {
		final Map<String,List< RedisKeyMemByte>> nodeToKeys = devideKeysRequest(requests);
		for (final String key : nodeToKeys.keySet()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
						List< RedisKeyMemByte>  subRequest= nodeToKeys.get(key);
						if (subRequest != null && subRequest.size() > 0) {
							 pipZrem(key,RedisData.getRedisKeyByteMemByteList(subRequest));
						}
				}
			});
		}
		
	}
	

	public void pipZremByte(List<RedisKeyMemByte> requests) {
		final Map<String,List< RedisKeyMemByte>> nodeToKeys = devideKeysRequest(requests);
		final CountDownLatch cdl = new CountDownLatch(nodeToKeys.keySet()
				.size());

		for (final String key : nodeToKeys.keySet()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
					try {
						List< RedisKeyMemByte>  subRequest= nodeToKeys.get(key);
						if (subRequest != null && subRequest.size() > 0) {
							 pipZrem(key,RedisData.getRedisKeyByteMemByteList(subRequest));
						}
					} finally {
						cdl.countDown();
					}
				}
			});
		}
		try {
			cdl.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	

	private void pipZrem(String key, List<RedisKeyByteMemByte>  requests) {
		
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Pipeline pipeline = jedis.pipelined();
				for(int i=0;i<requests.size();i++){
					pipeline.zrem(requests.get(i).getKey(), requests.get(i).getMem());
				}
				pipeline.syncAndReturnAll();
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
	}
	
	
	
	
	
	
	//zaddByteArr
	
	

	public void pipZaddObject(List<RedisKeySortMemObj> requests) {
		pipZaddByte(RedisSortData.getRedisKeySortMemByteListFromObj(requests)); 
	}
	
	public void pipZaddObjectAsyn(List<RedisKeySortMemObj> requests) {
		pipZaddByteAsyn(RedisSortData.getRedisKeySortMemByteListFromObj(requests)); 
	}
	
	public void pipZaddStr(List<RedisKeySortMemStr> requests) {
		pipZaddByte(RedisSortData.getRedisKeySortMemByteList(requests));
	}
	
	public void pipZaddStrAsyn(List<RedisKeySortMemStr> requests) {
		pipZaddByteAsyn(RedisSortData.getRedisKeySortMemByteList(requests));
	}
	
	
	public void pipZaddByteAsyn(List<RedisKeySortMemByte> requests) {
		final Map<String,List< RedisKeySortMemByte>> nodeToKeys = devideSortKeysRequest(requests);
		for (final String key : nodeToKeys.keySet()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
						List< RedisKeySortMemByte>  subRequest= nodeToKeys.get(key);
						if (subRequest != null && subRequest.size() > 0) {
							 pipZadd(key,RedisSortData.getRedisKeyByteMemByteList(subRequest));
						}
				}
			});
		}
		
	}
	

	public void pipZaddByte(List<RedisKeySortMemByte> requests) {
		final Map<String,List< RedisKeySortMemByte>> nodeToKeys = devideSortKeysRequest(requests);
		final CountDownLatch cdl = new CountDownLatch(nodeToKeys.keySet()
				.size());

		for (final String key : nodeToKeys.keySet()) {
			executorService.execute(new Runnable() {
				@Override
				public void run() {
					try {
						List< RedisKeySortMemByte>  subRequest= nodeToKeys.get(key);
						if (subRequest != null && subRequest.size() > 0) {
							 pipZadd(key,RedisSortData.getRedisKeyByteMemByteList(subRequest));
						}
					} finally {
						cdl.countDown();
					}
				}
			});
		}
		try {
			cdl.await();
		} catch (InterruptedException e) {
			e.printStackTrace();
		}
	}
	

	private void pipZadd(String key, List<RedisKeySortByteMemByte>  requests) {
		
		ShardedJedis shardJedis = null;
		Jedis jedis = null;
		try {
			int dbIndex = this.getDBIndex(key);
			shardJedis = shardedJedisPool.getResource();
			jedis = shardJedis.getShard(key);
			//jedis.select(dbIndex);
			if (jedis != null) {
				Pipeline pipeline = jedis.pipelined();
				for(int i=0;i<requests.size();i++){
					pipeline.zadd(requests.get(i).getKey(),requests.get(i).getSort(), requests.get(i).getMem());
				}
				pipeline.syncAndReturnAll();
			}
		} catch (Exception e) {
			if (shardJedis != null) {
				shardedJedisPool.returnBrokenResource(shardJedis);
			}
			log.error(e.getMessage()+jedis.getClient().getHost()+":"+jedis.getClient().getPort(), e);
			jedis = null;
		} finally {
			if (shardJedis != null) {
				shardedJedisPool.returnResource(shardJedis);
			}
		}
	}

	public JedisPoolConfig getJedisPoolConfig() {
		return jedisPoolConfig;
	}

	public ShardedJedisPool getShardedJedisPool() {
		return shardedJedisPool;
	}
	
	
	
	
	
	
	
	
	

	
	
}
